mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
chore: sync with main
This commit is contained in:
49
CHANGELOG.md
49
CHANGELOG.md
@ -3,6 +3,31 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* **datetime:** formatOptions property for Datetime ([#29065](https://github.com/ionic-team/ionic-framework/issues/29065)) ([7cdbc1b](https://github.com/ionic-team/ionic-framework/commit/7cdbc1b5ad004e17a7c51363653e0e67f50e6860))
|
||||||
|
* **searchbar:** autocapitalize, dir, lang, maxlength, and minlength are inherited to native input ([#29098](https://github.com/ionic-team/ionic-framework/issues/29098)) ([a0a77f7](https://github.com/ionic-team/ionic-framework/commit/a0a77f799df0732d9f7182f15866035a3ce5a1eb)), closes [#27606](https://github.com/ionic-team/ionic-framework/issues/27606)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **angular:** add ionNavWillChange and ionNavDidChange types for nav ([#29122](https://github.com/ionic-team/ionic-framework/issues/29122)) ([85b9d5c](https://github.com/ionic-team/ionic-framework/commit/85b9d5c35f626ffc273d220549b0126ddc1f7e4b)), closes [#29114](https://github.com/ionic-team/ionic-framework/issues/29114)
|
||||||
|
* **checkbox:** set aria-checked of indeterminate checkbox to 'mixed' ([#29115](https://github.com/ionic-team/ionic-framework/issues/29115)) ([b2d636f](https://github.com/ionic-team/ionic-framework/commit/b2d636f14dcd33313f6604cfd4a64b542c831b34))
|
||||||
|
* **overlay:** do not hide overlay if toast is presented ([#29140](https://github.com/ionic-team/ionic-framework/issues/29140)) ([c0f5e5e](https://github.com/ionic-team/ionic-framework/commit/c0f5e5ebc0c9d45d71e10e09903b00b3ba8e6bba)), closes [#29139](https://github.com/ionic-team/ionic-framework/issues/29139)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
|
|
||||||
@ -28,6 +53,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **modal:** ariaLabel and role are inherited when set via htmlAttributes ([#29099](https://github.com/ionic-team/ionic-framework/issues/29099)) ([de13633](https://github.com/ionic-team/ionic-framework/commit/de13633a182d963876434db773aa346833f956fd))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
|
||||||
@ -96,17 +134,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **modal:** ariaLabel and role are inherited when set via htmlAttributes ([#29099](https://github.com/ionic-team/ionic-framework/issues/29099)) ([de13633](https://github.com/ionic-team/ionic-framework/commit/de13633a182d963876434db773aa346833f956fd))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* **datetime:** formatOptions property for Datetime ([#29065](https://github.com/ionic-team/ionic-framework/issues/29065)) ([7cdbc1b](https://github.com/ionic-team/ionic-framework/commit/7cdbc1b5ad004e17a7c51363653e0e67f50e6860))
|
||||||
|
* **searchbar:** autocapitalize, dir, lang, maxlength, and minlength are inherited to native input ([#29098](https://github.com/ionic-team/ionic-framework/issues/29098)) ([a0a77f7](https://github.com/ionic-team/ionic-framework/commit/a0a77f799df0732d9f7182f15866035a3ce5a1eb)), closes [#27606](https://github.com/ionic-team/ionic-framework/issues/27606)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **checkbox:** set aria-checked of indeterminate checkbox to 'mixed' ([#29115](https://github.com/ionic-team/ionic-framework/issues/29115)) ([b2d636f](https://github.com/ionic-team/ionic-framework/commit/b2d636f14dcd33313f6604cfd4a64b542c831b34))
|
||||||
|
* **overlay:** do not hide overlay if toast is presented ([#29140](https://github.com/ionic-team/ionic-framework/issues/29140)) ([c0f5e5e](https://github.com/ionic-team/ionic-framework/commit/c0f5e5ebc0c9d45d71e10e09903b00b3ba8e6bba)), closes [#29139](https://github.com/ionic-team/ionic-framework/issues/29139)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
|
|
||||||
@ -28,6 +52,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **modal:** ariaLabel and role are inherited when set via htmlAttributes ([#29099](https://github.com/ionic-team/ionic-framework/issues/29099)) ([de13633](https://github.com/ionic-team/ionic-framework/commit/de13633a182d963876434db773aa346833f956fd))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
|
||||||
@ -42,11 +79,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
* **toggle:** set switch icon color correctly ([#28812](https://github.com/ionic-team/ionic-framework/issues/28812)) ([749df5b](https://github.com/ionic-team/ionic-framework/commit/749df5bdcec95e718199c4915c2a762ee29cdefb))
|
* **toggle:** set switch icon color correctly ([#28812](https://github.com/ionic-team/ionic-framework/issues/28812)) ([749df5b](https://github.com/ionic-team/ionic-framework/commit/749df5bdcec95e718199c4915c2a762ee29cdefb))
|
||||||
|
|
||||||
|
|
||||||
### chore
|
|
||||||
|
|
||||||
* remove unused code ([#28503](https://github.com/ionic-team/ionic-framework/issues/28503)) ([5aafd68](https://github.com/ionic-team/ionic-framework/commit/5aafd68f03bb6daefa9bfe58ce68459c3068fc5d))
|
|
||||||
|
|
||||||
|
|
||||||
### Code Refactoring
|
### Code Refactoring
|
||||||
|
|
||||||
* **checkbox:** remove legacy property and support for legacy syntax ([#29043](https://github.com/ionic-team/ionic-framework/issues/29043)) ([fb5ae5b](https://github.com/ionic-team/ionic-framework/commit/fb5ae5b07f98a3b62a35ab07192a0fc7898ecbea))
|
* **checkbox:** remove legacy property and support for legacy syntax ([#29043](https://github.com/ionic-team/ionic-framework/issues/29043)) ([fb5ae5b](https://github.com/ionic-team/ionic-framework/commit/fb5ae5b07f98a3b62a35ab07192a0fc7898ecbea))
|
||||||
@ -77,11 +109,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
* **toggle:** update styles to iOS 17 specs ([#28722](https://github.com/ionic-team/ionic-framework/issues/28722)) ([0ce0693](https://github.com/ionic-team/ionic-framework/commit/0ce0693af1cd468192ea58a08106c704da04640c))
|
* **toggle:** update styles to iOS 17 specs ([#28722](https://github.com/ionic-team/ionic-framework/issues/28722)) ([0ce0693](https://github.com/ionic-team/ionic-framework/commit/0ce0693af1cd468192ea58a08106c704da04640c))
|
||||||
|
|
||||||
|
|
||||||
### Reverts
|
|
||||||
|
|
||||||
* Revert "chore(): add updated snapshots" ([613bd54](https://github.com/ionic-team/ionic-framework/commit/613bd54adf519cef74e30066d549bd2ccc011b6a))
|
|
||||||
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
* **range:** The `legacy` property and support for the legacy syntax, which involved placing an `ion-range` inside of an `ion-item` with an `ion-label`, have been removed from range. For more information on migrating from the legacy range syntax, refer to the [Range documentation](https://ionicframework.com/docs/api/range#migrating-from-legacy-range-syntax).
|
* **range:** The `legacy` property and support for the legacy syntax, which involved placing an `ion-range` inside of an `ion-item` with an `ion-label`, have been removed from range. For more information on migrating from the legacy range syntax, refer to the [Range documentation](https://ionicframework.com/docs/api/range#migrating-from-legacy-range-syntax).
|
||||||
@ -98,17 +125,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **modal:** ariaLabel and role are inherited when set via htmlAttributes ([#29099](https://github.com/ionic-team/ionic-framework/issues/29099)) ([de13633](https://github.com/ionic-team/ionic-framework/commit/de13633a182d963876434db773aa346833f956fd))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,6 +394,7 @@ ion-datetime,prop,dayValues,number | number[] | string | undefined,undefined,fal
|
|||||||
ion-datetime,prop,disabled,boolean,false,false,false
|
ion-datetime,prop,disabled,boolean,false,false,false
|
||||||
ion-datetime,prop,doneText,string,'Done',false,false
|
ion-datetime,prop,doneText,string,'Done',false,false
|
||||||
ion-datetime,prop,firstDayOfWeek,number,0,false,false
|
ion-datetime,prop,firstDayOfWeek,number,0,false,false
|
||||||
|
ion-datetime,prop,formatOptions,undefined | { date: DateTimeFormatOptions; time?: DateTimeFormatOptions | undefined; } | { date?: DateTimeFormatOptions | undefined; time: DateTimeFormatOptions; },undefined,false,false
|
||||||
ion-datetime,prop,highlightedDates,((dateIsoString: string) => DatetimeHighlightStyle | undefined) | DatetimeHighlight[] | undefined,undefined,false,false
|
ion-datetime,prop,highlightedDates,((dateIsoString: string) => DatetimeHighlightStyle | undefined) | DatetimeHighlight[] | undefined,undefined,false,false
|
||||||
ion-datetime,prop,hourCycle,"h11" | "h12" | "h23" | "h24" | undefined,undefined,false,false
|
ion-datetime,prop,hourCycle,"h11" | "h12" | "h23" | "h24" | undefined,undefined,false,false
|
||||||
ion-datetime,prop,hourValues,number | number[] | string | undefined,undefined,false,false
|
ion-datetime,prop,hourValues,number | number[] | string | undefined,undefined,false,false
|
||||||
@ -1165,6 +1166,7 @@ ion-row,shadow
|
|||||||
|
|
||||||
ion-searchbar,scoped
|
ion-searchbar,scoped
|
||||||
ion-searchbar,prop,animated,boolean,false,false,false
|
ion-searchbar,prop,animated,boolean,false,false,false
|
||||||
|
ion-searchbar,prop,autocapitalize,string,undefined,true,false
|
||||||
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
|
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
|
||||||
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
|
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
|
||||||
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
|
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
|
||||||
@ -1175,6 +1177,8 @@ ion-searchbar,prop,debounce,number | undefined,undefined,false,false
|
|||||||
ion-searchbar,prop,disabled,boolean,false,false,false
|
ion-searchbar,prop,disabled,boolean,false,false,false
|
||||||
ion-searchbar,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
|
ion-searchbar,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
|
||||||
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
|
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
|
||||||
|
ion-searchbar,prop,maxlength,number | undefined,undefined,false,false
|
||||||
|
ion-searchbar,prop,minlength,number | undefined,undefined,false,false
|
||||||
ion-searchbar,prop,mode,"ios" | "md",undefined,false,false
|
ion-searchbar,prop,mode,"ios" | "md",undefined,false,false
|
||||||
ion-searchbar,prop,name,string,this.inputId,false,false
|
ion-searchbar,prop,name,string,this.inputId,false,false
|
||||||
ion-searchbar,prop,placeholder,string,'Search',false,false
|
ion-searchbar,prop,placeholder,string,'Search',false,false
|
||||||
|
36
core/src/components.d.ts
vendored
36
core/src/components.d.ts
vendored
@ -15,7 +15,7 @@ import { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./compo
|
|||||||
import { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
|
import { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
|
||||||
import { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
|
import { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
|
||||||
import { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
|
import { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
|
||||||
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
|
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, FormatOptions, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
|
||||||
import { SpinnerTypes } from "./components/spinner/spinner-configs";
|
import { SpinnerTypes } from "./components/spinner/spinner-configs";
|
||||||
import { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
|
import { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
|
||||||
import { MenuChangeEventDetail, MenuType, Side } from "./components/menu/menu-interface";
|
import { MenuChangeEventDetail, MenuType, Side } from "./components/menu/menu-interface";
|
||||||
@ -50,7 +50,7 @@ export { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./compo
|
|||||||
export { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
|
export { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
|
||||||
export { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
|
export { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
|
||||||
export { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
|
export { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
|
||||||
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
|
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, FormatOptions, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
|
||||||
export { SpinnerTypes } from "./components/spinner/spinner-configs";
|
export { SpinnerTypes } from "./components/spinner/spinner-configs";
|
||||||
export { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
|
export { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
|
||||||
export { MenuChangeEventDetail, MenuType, Side } from "./components/menu/menu-interface";
|
export { MenuChangeEventDetail, MenuType, Side } from "./components/menu/menu-interface";
|
||||||
@ -852,6 +852,10 @@ export namespace Components {
|
|||||||
* The first day of the week to use for `ion-datetime`. The default value is `0` and represents Sunday.
|
* The first day of the week to use for `ion-datetime`. The default value is `0` and represents Sunday.
|
||||||
*/
|
*/
|
||||||
"firstDayOfWeek": number;
|
"firstDayOfWeek": number;
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
"formatOptions"?: FormatOptions;
|
||||||
/**
|
/**
|
||||||
* 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"`.
|
* 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"`.
|
||||||
*/
|
*/
|
||||||
@ -2523,6 +2527,10 @@ export namespace Components {
|
|||||||
* If `true`, enable searchbar animation.
|
* If `true`, enable searchbar animation.
|
||||||
*/
|
*/
|
||||||
"animated": boolean;
|
"animated": boolean;
|
||||||
|
/**
|
||||||
|
* 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"`.
|
||||||
|
*/
|
||||||
|
"autocapitalize": string;
|
||||||
/**
|
/**
|
||||||
* Set the input's autocomplete property.
|
* Set the input's autocomplete property.
|
||||||
*/
|
*/
|
||||||
@ -2567,6 +2575,14 @@ export namespace Components {
|
|||||||
* A hint to the browser for which keyboard to display. Possible values: `"none"`, `"text"`, `"tel"`, `"url"`, `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
|
* A hint to the browser for which keyboard to display. Possible values: `"none"`, `"text"`, `"tel"`, `"url"`, `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
|
||||||
*/
|
*/
|
||||||
"inputmode"?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
"inputmode"?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
||||||
|
/**
|
||||||
|
* This attribute specifies the maximum number of characters that the user can enter.
|
||||||
|
*/
|
||||||
|
"maxlength"?: number;
|
||||||
|
/**
|
||||||
|
* This attribute specifies the minimum number of characters that the user can enter.
|
||||||
|
*/
|
||||||
|
"minlength"?: number;
|
||||||
/**
|
/**
|
||||||
* The mode determines which platform styles to use.
|
* The mode determines which platform styles to use.
|
||||||
*/
|
*/
|
||||||
@ -5500,6 +5516,10 @@ declare namespace LocalJSX {
|
|||||||
* The first day of the week to use for `ion-datetime`. The default value is `0` and represents Sunday.
|
* The first day of the week to use for `ion-datetime`. The default value is `0` and represents Sunday.
|
||||||
*/
|
*/
|
||||||
"firstDayOfWeek"?: number;
|
"firstDayOfWeek"?: number;
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
"formatOptions"?: FormatOptions;
|
||||||
/**
|
/**
|
||||||
* 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"`.
|
* 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"`.
|
||||||
*/
|
*/
|
||||||
@ -7196,6 +7216,10 @@ declare namespace LocalJSX {
|
|||||||
* If `true`, enable searchbar animation.
|
* If `true`, enable searchbar animation.
|
||||||
*/
|
*/
|
||||||
"animated"?: boolean;
|
"animated"?: boolean;
|
||||||
|
/**
|
||||||
|
* 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"`.
|
||||||
|
*/
|
||||||
|
"autocapitalize": string;
|
||||||
/**
|
/**
|
||||||
* Set the input's autocomplete property.
|
* Set the input's autocomplete property.
|
||||||
*/
|
*/
|
||||||
@ -7236,6 +7260,14 @@ declare namespace LocalJSX {
|
|||||||
* A hint to the browser for which keyboard to display. Possible values: `"none"`, `"text"`, `"tel"`, `"url"`, `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
|
* A hint to the browser for which keyboard to display. Possible values: `"none"`, `"text"`, `"tel"`, `"url"`, `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
|
||||||
*/
|
*/
|
||||||
"inputmode"?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
"inputmode"?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
||||||
|
/**
|
||||||
|
* This attribute specifies the maximum number of characters that the user can enter.
|
||||||
|
*/
|
||||||
|
"maxlength"?: number;
|
||||||
|
/**
|
||||||
|
* This attribute specifies the minimum number of characters that the user can enter.
|
||||||
|
*/
|
||||||
|
"minlength"?: number;
|
||||||
/**
|
/**
|
||||||
* The mode determines which platform styles to use.
|
* The mode determines which platform styles to use.
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { ComponentInterface } from '@stencil/core';
|
import type { ComponentInterface } from '@stencil/core';
|
||||||
import { Build, Component, Element, Host, Method, h } from '@stencil/core';
|
import { Build, Component, Element, Host, Method, h } from '@stencil/core';
|
||||||
import type { FocusVisibleUtility } from '@utils/focus-visible';
|
import type { FocusVisibleUtility } from '@utils/focus-visible';
|
||||||
import { shoudUseCloseWatcher } from '@utils/hardware-back-button';
|
import { shouldUseCloseWatcher } from '@utils/hardware-back-button';
|
||||||
import { printIonWarning } from '@utils/logging';
|
import { printIonWarning } from '@utils/logging';
|
||||||
import { isPlatform } from '@utils/platform';
|
import { isPlatform } from '@utils/platform';
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export class App implements ComponentInterface {
|
|||||||
import('../../utils/input-shims/input-shims').then((module) => module.startInputShims(config, platform));
|
import('../../utils/input-shims/input-shims').then((module) => module.startInputShims(config, platform));
|
||||||
}
|
}
|
||||||
const hardwareBackButtonModule = await import('../../utils/hardware-back-button');
|
const hardwareBackButtonModule = await import('../../utils/hardware-back-button');
|
||||||
const supportsHardwareBackButtonEvents = isHybrid || shoudUseCloseWatcher();
|
const supportsHardwareBackButtonEvents = isHybrid || shouldUseCloseWatcher();
|
||||||
if (config.getBoolean('hardwareBackButton', supportsHardwareBackButtonEvents)) {
|
if (config.getBoolean('hardwareBackButton', supportsHardwareBackButtonEvents)) {
|
||||||
hardwareBackButtonModule.startHardwareBackButton();
|
hardwareBackButtonModule.startHardwareBackButton();
|
||||||
} else {
|
} else {
|
||||||
@ -44,7 +44,7 @@ export class App implements ComponentInterface {
|
|||||||
* If an app sets hardwareBackButton: false and experimentalCloseWatcher: true
|
* If an app sets hardwareBackButton: false and experimentalCloseWatcher: true
|
||||||
* then the close watcher will not be used.
|
* then the close watcher will not be used.
|
||||||
*/
|
*/
|
||||||
if (shoudUseCloseWatcher()) {
|
if (shouldUseCloseWatcher()) {
|
||||||
printIonWarning(
|
printIonWarning(
|
||||||
'experimentalCloseWatcher was set to `true`, but hardwareBackButton was set to `false`. Both config options must be `true` for the Close Watcher API to be used.'
|
'experimentalCloseWatcher was set to `true`, but hardwareBackButton was set to `false`. Both config options must be `true` for the Close Watcher API to be used.'
|
||||||
);
|
);
|
||||||
|
@ -8,7 +8,7 @@ import { getIonMode } from '../../global/ionic-global';
|
|||||||
import type { Color } from '../../interface';
|
import type { Color } from '../../interface';
|
||||||
import type { DatetimePresentation } from '../datetime/datetime-interface';
|
import type { DatetimePresentation } from '../datetime/datetime-interface';
|
||||||
import { getToday } from '../datetime/utils/data';
|
import { getToday } from '../datetime/utils/data';
|
||||||
import { getMonthAndYear, getMonthDayAndYear, getLocalizedDateTime, getLocalizedTime } from '../datetime/utils/format';
|
import { getLocalizedDateTime, getLocalizedTime } from '../datetime/utils/format';
|
||||||
import { getHourCycle } from '../datetime/utils/helpers';
|
import { getHourCycle } from '../datetime/utils/helpers';
|
||||||
import { parseDate } from '../datetime/utils/parse';
|
import { parseDate } from '../datetime/utils/parse';
|
||||||
/**
|
/**
|
||||||
@ -196,7 +196,7 @@ export class DatetimeButton implements ComponentInterface {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { value, locale, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
|
const { value, locale, formatOptions, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
|
||||||
|
|
||||||
const parsedValues = this.getParsedDateValues(value);
|
const parsedValues = this.getParsedDateValues(value);
|
||||||
|
|
||||||
@ -225,8 +225,12 @@ export class DatetimeButton implements ComponentInterface {
|
|||||||
switch (datetimePresentation) {
|
switch (datetimePresentation) {
|
||||||
case 'date-time':
|
case 'date-time':
|
||||||
case 'time-date':
|
case 'time-date':
|
||||||
const dateText = getMonthDayAndYear(locale, firstParsedDatetime);
|
const dateText = getLocalizedDateTime(
|
||||||
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
|
locale,
|
||||||
|
firstParsedDatetime,
|
||||||
|
formatOptions?.date ?? { month: 'short', day: 'numeric', year: 'numeric' }
|
||||||
|
);
|
||||||
|
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions?.time);
|
||||||
if (preferWheel) {
|
if (preferWheel) {
|
||||||
this.dateText = `${dateText} ${timeText}`;
|
this.dateText = `${dateText} ${timeText}`;
|
||||||
} else {
|
} else {
|
||||||
@ -246,20 +250,28 @@ export class DatetimeButton implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
this.dateText = headerText;
|
this.dateText = headerText;
|
||||||
} else {
|
} else {
|
||||||
this.dateText = getMonthDayAndYear(locale, firstParsedDatetime);
|
this.dateText = getLocalizedDateTime(
|
||||||
|
locale,
|
||||||
|
firstParsedDatetime,
|
||||||
|
formatOptions?.date ?? { month: 'short', day: 'numeric', year: 'numeric' }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'time':
|
case 'time':
|
||||||
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
|
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions?.time);
|
||||||
break;
|
break;
|
||||||
case 'month-year':
|
case 'month-year':
|
||||||
this.dateText = getMonthAndYear(locale, firstParsedDatetime);
|
this.dateText = getLocalizedDateTime(
|
||||||
|
locale,
|
||||||
|
firstParsedDatetime,
|
||||||
|
formatOptions?.date ?? { month: 'long', year: 'numeric' }
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'month':
|
case 'month':
|
||||||
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { month: 'long' });
|
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, formatOptions?.time ?? { month: 'long' });
|
||||||
break;
|
break;
|
||||||
case 'year':
|
case 'year':
|
||||||
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, { year: 'numeric' });
|
this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, formatOptions?.time ?? { year: 'numeric' });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -261,4 +261,87 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|||||||
await expect(page.locator('#time-button')).not.toBeVisible();
|
await expect(page.locator('#time-button')).not.toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.describe(title('datetime-button: formatOptions'), () => {
|
||||||
|
test('should include date and time for presentation date-time', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
||||||
|
<ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US"></ion-datetime>
|
||||||
|
<script>
|
||||||
|
const datetime = document.querySelector('ion-datetime');
|
||||||
|
datetime.formatOptions = {
|
||||||
|
date: {
|
||||||
|
weekday: "short",
|
||||||
|
month: "long",
|
||||||
|
day: "2-digit"
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.locator('.datetime-ready').waitFor();
|
||||||
|
|
||||||
|
await expect(page.locator('#date-button')).toContainText('Thu, November 02');
|
||||||
|
await expect(page.locator('#time-button')).toContainText('01:22 AM');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should include date for presentation date', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
||||||
|
<ion-datetime id="datetime" presentation="date" value="2023-11-02" locale="en-US"></ion-datetime>
|
||||||
|
<script>
|
||||||
|
const datetime = document.querySelector('ion-datetime');
|
||||||
|
datetime.formatOptions = {
|
||||||
|
date: {
|
||||||
|
weekday: "short",
|
||||||
|
month: "long",
|
||||||
|
day: "2-digit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.locator('.datetime-ready').waitFor();
|
||||||
|
|
||||||
|
await expect(page.locator('#date-button')).toContainText('Thu, November 02');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should include date and time in same button for preferWheel', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
||||||
|
<ion-datetime id="datetime" presentation="date-time" value="2023-11-02T01:22:00" locale="en-US" prefer-wheel="true"></ion-datetime>
|
||||||
|
<script>
|
||||||
|
const datetime = document.querySelector('ion-datetime');
|
||||||
|
datetime.formatOptions = {
|
||||||
|
date: {
|
||||||
|
weekday: "short",
|
||||||
|
month: "long",
|
||||||
|
day: "2-digit"
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.locator('.datetime-ready').waitFor();
|
||||||
|
|
||||||
|
await expect(page.locator('ion-datetime-button')).toContainText('Thu, November 02 01:22 AM');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -215,8 +215,41 @@
|
|||||||
></ion-datetime>
|
></ion-datetime>
|
||||||
</ion-popover>
|
</ion-popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2>formatOptions</h2>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Start Date</ion-label>
|
||||||
|
<ion-datetime-button datetime="format-options" slot="end"></ion-datetime-button>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-popover arrow="false">
|
||||||
|
<ion-datetime
|
||||||
|
id="format-options"
|
||||||
|
presentation="date-time"
|
||||||
|
value="2023-11-02T01:22:00"
|
||||||
|
locale="en-US"
|
||||||
|
></ion-datetime>
|
||||||
|
</ion-popover>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
</ion-app>
|
</ion-app>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const formatOptionsDatetime = document.querySelector('#format-options');
|
||||||
|
formatOptionsDatetime.formatOptions = {
|
||||||
|
date: {
|
||||||
|
weekday: 'short',
|
||||||
|
month: 'long',
|
||||||
|
day: '2-digit',
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
@ -36,3 +36,16 @@ export type DatetimeHighlight = { date: string } & DatetimeHighlightStyle;
|
|||||||
export type DatetimeHighlightCallback = (dateIsoString: string) => DatetimeHighlightStyle | undefined;
|
export type DatetimeHighlightCallback = (dateIsoString: string) => DatetimeHighlightStyle | undefined;
|
||||||
|
|
||||||
export type DatetimeHourCycle = 'h11' | 'h12' | 'h23' | 'h24';
|
export type DatetimeHourCycle = 'h11' | 'h12' | 'h23' | 'h24';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FormatOptions must include date and/or time; it cannot be an empty object
|
||||||
|
*/
|
||||||
|
export type FormatOptions =
|
||||||
|
| {
|
||||||
|
date: Intl.DateTimeFormatOptions;
|
||||||
|
time?: Intl.DateTimeFormatOptions;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
date?: Intl.DateTimeFormatOptions;
|
||||||
|
time: Intl.DateTimeFormatOptions;
|
||||||
|
};
|
||||||
|
@ -19,6 +19,7 @@ import type {
|
|||||||
DatetimeHighlightStyle,
|
DatetimeHighlightStyle,
|
||||||
DatetimeHighlightCallback,
|
DatetimeHighlightCallback,
|
||||||
DatetimeHourCycle,
|
DatetimeHourCycle,
|
||||||
|
FormatOptions,
|
||||||
} from './datetime-interface';
|
} from './datetime-interface';
|
||||||
import { isSameDay, warnIfValueOutOfBounds, isBefore, isAfter } from './utils/comparison';
|
import { isSameDay, warnIfValueOutOfBounds, isBefore, isAfter } from './utils/comparison';
|
||||||
import type { WheelColumnOption } from './utils/data';
|
import type { WheelColumnOption } from './utils/data';
|
||||||
@ -33,7 +34,7 @@ import {
|
|||||||
getTimeColumnsData,
|
getTimeColumnsData,
|
||||||
getCombinedDateColumnData,
|
getCombinedDateColumnData,
|
||||||
} from './utils/data';
|
} from './utils/data';
|
||||||
import { formatValue, getLocalizedTime, getMonthAndDay, getMonthAndYear } from './utils/format';
|
import { formatValue, getLocalizedDateTime, getLocalizedTime, getMonthAndYear } from './utils/format';
|
||||||
import { isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth, getHourCycle } from './utils/helpers';
|
import { isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth, getHourCycle } from './utils/helpers';
|
||||||
import {
|
import {
|
||||||
calculateHourFromAMPM,
|
calculateHourFromAMPM,
|
||||||
@ -68,6 +69,7 @@ import {
|
|||||||
isNextMonthDisabled,
|
isNextMonthDisabled,
|
||||||
isPrevMonthDisabled,
|
isPrevMonthDisabled,
|
||||||
} from './utils/state';
|
} from './utils/state';
|
||||||
|
import { checkForPresentationFormatMismatch, warnIfTimeZoneProvided } from './utils/validate';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||||
@ -170,6 +172,20 @@ export class Datetime implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() disabled = false;
|
@Prop() disabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Prop() formatOptions?: FormatOptions;
|
||||||
|
|
||||||
|
@Watch('formatOptions')
|
||||||
|
protected formatOptionsChanged() {
|
||||||
|
const { el, formatOptions, presentation } = this;
|
||||||
|
checkForPresentationFormatMismatch(el, presentation, formatOptions);
|
||||||
|
warnIfTimeZoneProvided(el, formatOptions);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `true`, the datetime appears normal but the selected date cannot be changed.
|
* If `true`, the datetime appears normal but the selected date cannot be changed.
|
||||||
*/
|
*/
|
||||||
@ -234,6 +250,12 @@ export class Datetime implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() presentation: DatetimePresentation = 'date-time';
|
@Prop() presentation: DatetimePresentation = 'date-time';
|
||||||
|
|
||||||
|
@Watch('presentation')
|
||||||
|
protected presentationChanged() {
|
||||||
|
const { el, formatOptions, presentation } = this;
|
||||||
|
checkForPresentationFormatMismatch(el, presentation, formatOptions);
|
||||||
|
}
|
||||||
|
|
||||||
private get isGridStyle() {
|
private get isGridStyle() {
|
||||||
const { presentation, preferWheel } = this;
|
const { presentation, preferWheel } = this;
|
||||||
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
||||||
@ -1356,7 +1378,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentWillLoad() {
|
componentWillLoad() {
|
||||||
const { el, highlightedDates, multiple, presentation, preferWheel } = this;
|
const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
|
||||||
|
|
||||||
if (multiple) {
|
if (multiple) {
|
||||||
if (presentation !== 'date') {
|
if (presentation !== 'date') {
|
||||||
@ -1381,6 +1403,11 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (formatOptions) {
|
||||||
|
checkForPresentationFormatMismatch(el, presentation, formatOptions);
|
||||||
|
warnIfTimeZoneProvided(el, formatOptions);
|
||||||
|
}
|
||||||
|
|
||||||
const hourValues = (this.parsedHourValues = convertToArrayOfNumbers(this.hourValues));
|
const hourValues = (this.parsedHourValues = convertToArrayOfNumbers(this.hourValues));
|
||||||
const minuteValues = (this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues));
|
const minuteValues = (this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues));
|
||||||
const monthValues = (this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues));
|
const monthValues = (this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues));
|
||||||
@ -2362,7 +2389,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderTimeOverlay() {
|
private renderTimeOverlay() {
|
||||||
const { disabled, hourCycle, isTimePopoverOpen, locale } = this;
|
const { disabled, hourCycle, isTimePopoverOpen, locale, formatOptions } = this;
|
||||||
const computedHourCycle = getHourCycle(locale, hourCycle);
|
const computedHourCycle = getHourCycle(locale, hourCycle);
|
||||||
const activePart = this.getActivePartsWithFallback();
|
const activePart = this.getActivePartsWithFallback();
|
||||||
|
|
||||||
@ -2397,7 +2424,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{getLocalizedTime(locale, activePart, computedHourCycle)}
|
{getLocalizedTime(locale, activePart, computedHourCycle, formatOptions?.time)}
|
||||||
</button>,
|
</button>,
|
||||||
<ion-popover
|
<ion-popover
|
||||||
alignment="center"
|
alignment="center"
|
||||||
@ -2432,7 +2459,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getHeaderSelectedDateText() {
|
private getHeaderSelectedDateText() {
|
||||||
const { activeParts, multiple, titleSelectedDatesFormatter } = this;
|
const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
|
||||||
const isArray = Array.isArray(activeParts);
|
const isArray = Array.isArray(activeParts);
|
||||||
|
|
||||||
let headerText: string;
|
let headerText: string;
|
||||||
@ -2447,7 +2474,11 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// for exactly 1 day selected (multiple set or not), show a formatted version of that
|
// for exactly 1 day selected (multiple set or not), show a formatted version of that
|
||||||
headerText = getMonthAndDay(this.locale, this.getActivePartsWithFallback());
|
headerText = getLocalizedDateTime(
|
||||||
|
this.locale,
|
||||||
|
this.getActivePartsWithFallback(),
|
||||||
|
formatOptions?.date ?? { weekday: 'short', month: 'short', day: 'numeric' }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return headerText;
|
return headerText;
|
||||||
|
@ -586,3 +586,107 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This behavior does not differ across
|
||||||
|
* directions.
|
||||||
|
*/
|
||||||
|
configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||||
|
test.describe(title('datetime: formatOptions'), () => {
|
||||||
|
test('should format header and time button', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-datetime value="2022-02-01T16:30:00">
|
||||||
|
<span slot="title">Select Date</span>
|
||||||
|
</ion-datetime>
|
||||||
|
<script>
|
||||||
|
const datetime = document.querySelector('ion-datetime');
|
||||||
|
datetime.formatOptions = {
|
||||||
|
time: { hour: '2-digit', minute: '2-digit' },
|
||||||
|
date: { day: '2-digit', month: 'long', era: 'short' },
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.locator('.datetime-ready').waitFor();
|
||||||
|
|
||||||
|
const headerDate = page.locator('ion-datetime .datetime-selected-date');
|
||||||
|
await expect(headerDate).toHaveText('February 01 AD');
|
||||||
|
|
||||||
|
const timeBody = page.locator('ion-datetime .time-body');
|
||||||
|
await expect(timeBody).toHaveText('04:30 PM');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This behavior does not differ across
|
||||||
|
* modes/directions.
|
||||||
|
*/
|
||||||
|
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||||
|
test.describe(title('datetime: formatOptions misconfiguration errors'), () => {
|
||||||
|
test('should log a warning if time zone is provided', async ({ page }) => {
|
||||||
|
const logs: string[] = [];
|
||||||
|
|
||||||
|
page.on('console', (msg) => {
|
||||||
|
if (msg.type() === 'warning') {
|
||||||
|
logs.push(msg.text());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-datetime value="2022-02-01T16:30:00" presentation="date">
|
||||||
|
<span slot="title">Select Date</span>
|
||||||
|
</ion-datetime>
|
||||||
|
<script>
|
||||||
|
const datetime = document.querySelector('ion-datetime');
|
||||||
|
datetime.formatOptions = {
|
||||||
|
date: { timeZone: 'UTC' },
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.locator('.datetime-ready').waitFor();
|
||||||
|
|
||||||
|
expect(logs.length).toBe(1);
|
||||||
|
expect(logs[0]).toContain(
|
||||||
|
'[Ionic Warning]: Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should log a warning if the required formatOptions are not provided for a presentation', async ({ page }) => {
|
||||||
|
const logs: string[] = [];
|
||||||
|
|
||||||
|
page.on('console', (msg) => {
|
||||||
|
if (msg.type() === 'warning') {
|
||||||
|
logs.push(msg.text());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<ion-datetime value="2022-02-01T16:30:00">
|
||||||
|
<span slot="title">Select Date</span>
|
||||||
|
</ion-datetime>
|
||||||
|
<script>
|
||||||
|
const datetime = document.querySelector('ion-datetime');
|
||||||
|
datetime.formatOptions = {}
|
||||||
|
</script>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.locator('.datetime-ready').waitFor();
|
||||||
|
|
||||||
|
expect(logs.length).toBe(1);
|
||||||
|
expect(logs[0]).toContain(
|
||||||
|
"[Ionic Warning]: Datetime: The 'date-time' presentation requires either a date or time object (or both) in formatOptions."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -308,6 +308,13 @@
|
|||||||
</ion-datetime>
|
</ion-datetime>
|
||||||
</ion-modal>
|
</ion-modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2>formatOptions</h2>
|
||||||
|
<ion-datetime value="2020-03-14T14:23:00.000Z" id="format-options-datetime">
|
||||||
|
<span slot="title">Select Date</span>
|
||||||
|
</ion-datetime>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<script>
|
<script>
|
||||||
@ -403,6 +410,12 @@
|
|||||||
app.appendChild(modalElement);
|
app.appendChild(modalElement);
|
||||||
return modalElement;
|
return modalElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formatOptions = document.querySelector('#format-options-datetime');
|
||||||
|
formatOptions.formatOptions = {
|
||||||
|
time: { hour: '2-digit', minute: '2-digit' },
|
||||||
|
date: { day: '2-digit', month: 'long', era: 'short' },
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
</ion-app>
|
</ion-app>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import type { DatetimeParts } from '../datetime-interface';
|
import type { DatetimeParts } from '../datetime-interface';
|
||||||
import {
|
import {
|
||||||
generateDayAriaLabel,
|
generateDayAriaLabel,
|
||||||
getMonthAndDay,
|
|
||||||
getFormattedHour,
|
getFormattedHour,
|
||||||
addTimePadding,
|
addTimePadding,
|
||||||
getMonthAndYear,
|
getMonthAndYear,
|
||||||
getLocalizedDayPeriod,
|
getLocalizedDayPeriod,
|
||||||
getLocalizedTime,
|
getLocalizedTime,
|
||||||
|
stripTimeZone,
|
||||||
} from '../utils/format';
|
} from '../utils/format';
|
||||||
|
|
||||||
describe('generateDayAriaLabel()', () => {
|
describe('generateDayAriaLabel()', () => {
|
||||||
@ -37,24 +37,6 @@ describe('generateDayAriaLabel()', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getMonthAndDay()', () => {
|
|
||||||
it('should return Tue, May 11', () => {
|
|
||||||
expect(getMonthAndDay('en-US', { month: 5, day: 11, year: 2021 })).toEqual('Tue, May 11');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return mar, 11 may', () => {
|
|
||||||
expect(getMonthAndDay('es-ES', { month: 5, day: 11, year: 2021 })).toEqual('mar, 11 may');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return Sat, Apr 1', () => {
|
|
||||||
expect(getMonthAndDay('en-US', { month: 4, day: 1, year: 2006 })).toEqual('Sat, Apr 1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return sáb, 1 abr', () => {
|
|
||||||
expect(getMonthAndDay('es-ES', { month: 4, day: 1, year: 2006 })).toEqual('sáb, 1 abr');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getFormattedHour()', () => {
|
describe('getFormattedHour()', () => {
|
||||||
it('should only add padding if using 24 hour time', () => {
|
it('should only add padding if using 24 hour time', () => {
|
||||||
expect(getFormattedHour(1, 'h11')).toEqual('1');
|
expect(getFormattedHour(1, 'h11')).toEqual('1');
|
||||||
@ -144,6 +126,7 @@ describe('getLocalizedTime', () => {
|
|||||||
|
|
||||||
expect(getLocalizedTime('en-GB', datetimeParts, 'h12')).toEqual('12:00 am');
|
expect(getLocalizedTime('en-GB', datetimeParts, 'h12')).toEqual('12:00 am');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse time-only values correctly', () => {
|
it('should parse time-only values correctly', () => {
|
||||||
const datetimeParts: Partial<DatetimeParts> = {
|
const datetimeParts: Partial<DatetimeParts> = {
|
||||||
hour: 22,
|
hour: 22,
|
||||||
@ -153,4 +136,79 @@ describe('getLocalizedTime', () => {
|
|||||||
expect(getLocalizedTime('en-US', datetimeParts as DatetimeParts, 'h12')).toEqual('10:40 PM');
|
expect(getLocalizedTime('en-US', datetimeParts as DatetimeParts, 'h12')).toEqual('10:40 PM');
|
||||||
expect(getLocalizedTime('en-US', datetimeParts as DatetimeParts, 'h23')).toEqual('22:40');
|
expect(getLocalizedTime('en-US', datetimeParts as DatetimeParts, 'h23')).toEqual('22:40');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should use formatOptions', () => {
|
||||||
|
const datetimeParts: DatetimeParts = {
|
||||||
|
day: 1,
|
||||||
|
month: 1,
|
||||||
|
year: 2022,
|
||||||
|
hour: 9,
|
||||||
|
minute: 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatOptions: Intl.DateTimeFormatOptions = {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
dayPeriod: 'short',
|
||||||
|
day: '2-digit',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Even though this method is intended to be used for time, the date may be displayed as well when passing formatOptions
|
||||||
|
expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('01, 09:40 in the morning');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should override provided time zone with UTC', () => {
|
||||||
|
const datetimeParts: DatetimeParts = {
|
||||||
|
day: 1,
|
||||||
|
month: 1,
|
||||||
|
year: 2022,
|
||||||
|
hour: 9,
|
||||||
|
minute: 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatOptions: Intl.DateTimeFormatOptions = {
|
||||||
|
timeZone: 'Australia/Sydney',
|
||||||
|
timeZoneName: 'long',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('9:40 AM');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include time zone name', () => {
|
||||||
|
const datetimeParts: DatetimeParts = {
|
||||||
|
day: 1,
|
||||||
|
month: 1,
|
||||||
|
year: 2022,
|
||||||
|
hour: 9,
|
||||||
|
minute: 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatOptions: Intl.DateTimeFormatOptions = {
|
||||||
|
timeZone: 'America/Los_Angeles',
|
||||||
|
timeZoneName: 'long',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getLocalizedTime('en-US', datetimeParts, 'h12', formatOptions)).toEqual('9:40 AM');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('stripTimeZone', () => {
|
||||||
|
it('should remove the time zone name from the options and set the time zone to UTC', () => {
|
||||||
|
const formatOptions: Intl.DateTimeFormatOptions = {
|
||||||
|
timeZone: 'America/Los_Angeles',
|
||||||
|
timeZoneName: 'long',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(stripTimeZone(formatOptions)).toEqual({
|
||||||
|
timeZone: 'UTC',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,33 @@ const getFormattedDayPeriod = (dayPeriod?: string) => {
|
|||||||
return dayPeriod.toUpperCase();
|
return dayPeriod.toUpperCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getLocalizedTime = (locale: string, refParts: DatetimeParts, hourCycle: DatetimeHourCycle): string => {
|
/**
|
||||||
|
* Including time zone options may lead to the rendered text showing a
|
||||||
|
* different time from what was selected in the Datetime, which could cause
|
||||||
|
* confusion.
|
||||||
|
*/
|
||||||
|
export const stripTimeZone = (formatOptions: Intl.DateTimeFormatOptions): Intl.DateTimeFormatOptions => {
|
||||||
|
return {
|
||||||
|
...formatOptions,
|
||||||
|
/**
|
||||||
|
* Setting the time zone to UTC ensures that the value shown is always the
|
||||||
|
* same as what was selected and safeguards against older Safari bugs with
|
||||||
|
* Intl.DateTimeFormat.
|
||||||
|
*/
|
||||||
|
timeZone: 'UTC',
|
||||||
|
/**
|
||||||
|
* We do not want to display the time zone name
|
||||||
|
*/
|
||||||
|
timeZoneName: undefined,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLocalizedTime = (
|
||||||
|
locale: string,
|
||||||
|
refParts: DatetimeParts,
|
||||||
|
hourCycle: DatetimeHourCycle,
|
||||||
|
formatOptions: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric' }
|
||||||
|
): string => {
|
||||||
const timeParts: Pick<DatetimeParts, 'hour' | 'minute'> = {
|
const timeParts: Pick<DatetimeParts, 'hour' | 'minute'> = {
|
||||||
hour: refParts.hour,
|
hour: refParts.hour,
|
||||||
minute: refParts.minute,
|
minute: refParts.minute,
|
||||||
@ -22,15 +48,7 @@ export const getLocalizedTime = (locale: string, refParts: DatetimeParts, hourCy
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Intl.DateTimeFormat(locale, {
|
return new Intl.DateTimeFormat(locale, {
|
||||||
hour: 'numeric',
|
...stripTimeZone(formatOptions),
|
||||||
minute: 'numeric',
|
|
||||||
/**
|
|
||||||
* Setting the timeZone to UTC prevents
|
|
||||||
* new Intl.DatetimeFormat from subtracting
|
|
||||||
* the user's current timezone offset
|
|
||||||
* when formatting the time.
|
|
||||||
*/
|
|
||||||
timeZone: 'UTC',
|
|
||||||
/**
|
/**
|
||||||
* We use hourCycle here instead of hour12 due to:
|
* We use hourCycle here instead of hour12 due to:
|
||||||
* https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
|
* https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
|
||||||
@ -146,17 +164,6 @@ export const generateDayAriaLabel = (locale: string, today: boolean, refParts: D
|
|||||||
return today ? `Today, ${labelString}` : labelString;
|
return today ? `Today, ${labelString}` : labelString;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the day of the week, month, and day
|
|
||||||
* Used for the header in MD mode.
|
|
||||||
*/
|
|
||||||
export const getMonthAndDay = (locale: string, refParts: DatetimeParts) => {
|
|
||||||
const date = getNormalizedDate(refParts);
|
|
||||||
return new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric', timeZone: 'UTC' }).format(
|
|
||||||
date
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a locale and a date object,
|
* Given a locale and a date object,
|
||||||
* return a formatted string that includes
|
* return a formatted string that includes
|
||||||
@ -168,16 +175,6 @@ export const getMonthAndYear = (locale: string, refParts: DatetimeParts) => {
|
|||||||
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
|
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a locale and a date object,
|
|
||||||
* return a formatted string that includes
|
|
||||||
* the short month, numeric day, and full year.
|
|
||||||
* Example: Apr 22, 2021
|
|
||||||
*/
|
|
||||||
export const getMonthDayAndYear = (locale: string, refParts: DatetimeParts) => {
|
|
||||||
return getLocalizedDateTime(locale, refParts, { month: 'short', day: 'numeric', year: 'numeric' });
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a locale and a date object,
|
* Given a locale and a date object,
|
||||||
* return a formatted string that includes
|
* return a formatted string that includes
|
||||||
@ -235,7 +232,7 @@ export const getLocalizedDateTime = (
|
|||||||
options: Intl.DateTimeFormatOptions
|
options: Intl.DateTimeFormatOptions
|
||||||
): string => {
|
): string => {
|
||||||
const date = getNormalizedDate(refParts);
|
const date = getNormalizedDate(refParts);
|
||||||
return getDateTimeFormat(locale, options).format(date);
|
return getDateTimeFormat(locale, stripTimeZone(options)).format(date);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
54
core/src/components/datetime/utils/validate.ts
Normal file
54
core/src/components/datetime/utils/validate.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { printIonWarning } from '@utils/logging';
|
||||||
|
|
||||||
|
import type { DatetimePresentation, FormatOptions } from '../datetime-interface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a time zone is provided in the format options, the rendered text could
|
||||||
|
* differ from what was selected in the Datetime, which could cause
|
||||||
|
* confusion.
|
||||||
|
*/
|
||||||
|
export const warnIfTimeZoneProvided = (el: HTMLElement, formatOptions?: FormatOptions) => {
|
||||||
|
if (
|
||||||
|
formatOptions?.date?.timeZone ||
|
||||||
|
formatOptions?.date?.timeZoneName ||
|
||||||
|
formatOptions?.time?.timeZone ||
|
||||||
|
formatOptions?.time?.timeZoneName
|
||||||
|
) {
|
||||||
|
printIonWarning('Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".', el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkForPresentationFormatMismatch = (
|
||||||
|
el: HTMLElement,
|
||||||
|
presentation: DatetimePresentation,
|
||||||
|
formatOptions?: FormatOptions
|
||||||
|
) => {
|
||||||
|
// formatOptions is not required
|
||||||
|
if (!formatOptions) return;
|
||||||
|
|
||||||
|
// If formatOptions is provided, the date and/or time objects are required, depending on the presentation
|
||||||
|
switch (presentation) {
|
||||||
|
case 'date':
|
||||||
|
case 'month-year':
|
||||||
|
case 'month':
|
||||||
|
case 'year':
|
||||||
|
if (formatOptions.date === undefined) {
|
||||||
|
printIonWarning(`Datetime: The '${presentation}' presentation requires a date object in formatOptions.`, el);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'time':
|
||||||
|
if (formatOptions.time === undefined) {
|
||||||
|
printIonWarning(`Datetime: The 'time' presentation requires a time object in formatOptions.`, el);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'date-time':
|
||||||
|
case 'time-date':
|
||||||
|
if (formatOptions.date === undefined && formatOptions.time === undefined) {
|
||||||
|
printIonWarning(
|
||||||
|
`Datetime: The '${presentation}' presentation requires either a date or time object (or both) in formatOptions.`,
|
||||||
|
el
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
@ -3,7 +3,7 @@ import { Build, Component, Element, Event, Host, Listen, Method, Prop, State, Wa
|
|||||||
import { getTimeGivenProgression } from '@utils/animation/cubic-bezier';
|
import { getTimeGivenProgression } from '@utils/animation/cubic-bezier';
|
||||||
import { focusFirstDescendant, focusLastDescendant } from '@utils/focus-trap';
|
import { focusFirstDescendant, focusLastDescendant } from '@utils/focus-trap';
|
||||||
import { GESTURE_CONTROLLER } from '@utils/gesture';
|
import { GESTURE_CONTROLLER } from '@utils/gesture';
|
||||||
import { shoudUseCloseWatcher } from '@utils/hardware-back-button';
|
import { shouldUseCloseWatcher } from '@utils/hardware-back-button';
|
||||||
import type { Attributes } from '@utils/helpers';
|
import type { Attributes } from '@utils/helpers';
|
||||||
import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from '@utils/helpers';
|
import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from '@utils/helpers';
|
||||||
import { menuController } from '@utils/menu-controller';
|
import { menuController } from '@utils/menu-controller';
|
||||||
@ -782,7 +782,7 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
*/
|
*/
|
||||||
return (
|
return (
|
||||||
<Host
|
<Host
|
||||||
onKeyDown={shoudUseCloseWatcher() ? null : this.onKeydown}
|
onKeyDown={shouldUseCloseWatcher() ? null : this.onKeydown}
|
||||||
role="navigation"
|
role="navigation"
|
||||||
aria-label={inheritedAttributes['aria-label'] || 'menu'}
|
aria-label={inheritedAttributes['aria-label'] || 'menu'}
|
||||||
class={{
|
class={{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||||
import { Component, Element, Event, Host, Method, Prop, State, Watch, forceUpdate, h } from '@stencil/core';
|
import { Component, Element, Event, Host, Method, Prop, State, Watch, forceUpdate, h } from '@stencil/core';
|
||||||
import { debounceEvent, raf, componentOnReady } from '@utils/helpers';
|
import { debounceEvent, raf, componentOnReady, inheritAttributes } from '@utils/helpers';
|
||||||
|
import type { Attributes } from '@utils/helpers';
|
||||||
import { isRTL } from '@utils/rtl';
|
import { isRTL } from '@utils/rtl';
|
||||||
import { createColorClasses } from '@utils/theme';
|
import { createColorClasses } from '@utils/theme';
|
||||||
import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
||||||
@ -28,6 +29,7 @@ export class Searchbar implements ComponentInterface {
|
|||||||
private shouldAlignLeft = true;
|
private shouldAlignLeft = true;
|
||||||
private originalIonInput?: EventEmitter<SearchbarInputEventDetail>;
|
private originalIonInput?: EventEmitter<SearchbarInputEventDetail>;
|
||||||
private inputId = `ion-searchbar-${searchbarIds++}`;
|
private inputId = `ion-searchbar-${searchbarIds++}`;
|
||||||
|
private inheritedAttributes: Attributes = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of the input when the textarea is focused.
|
* The value of the input when the textarea is focused.
|
||||||
@ -39,6 +41,31 @@ export class Searchbar implements ComponentInterface {
|
|||||||
@State() focused = false;
|
@State() focused = false;
|
||||||
@State() noAnimate = true;
|
@State() noAnimate = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lang and dir are globally enumerated attributes.
|
||||||
|
* As a result, creating these as properties
|
||||||
|
* can have unintended side effects. Instead, we
|
||||||
|
* listen for attribute changes and inherit them
|
||||||
|
* to the inner `<input>` element.
|
||||||
|
*/
|
||||||
|
@Watch('lang')
|
||||||
|
onLangChanged(newValue: string) {
|
||||||
|
this.inheritedAttributes = {
|
||||||
|
...this.inheritedAttributes,
|
||||||
|
lang: newValue,
|
||||||
|
};
|
||||||
|
forceUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch('dir')
|
||||||
|
onDirChanged(newValue: string) {
|
||||||
|
this.inheritedAttributes = {
|
||||||
|
...this.inheritedAttributes,
|
||||||
|
dir: newValue,
|
||||||
|
};
|
||||||
|
forceUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color to use from your application's color palette.
|
* The color to use from your application's color palette.
|
||||||
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
|
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
|
||||||
@ -51,6 +78,27 @@ export class Searchbar implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() animated = false;
|
@Prop() animated = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prior to the addition of this property
|
||||||
|
* autocapitalize was enabled by default on iOS
|
||||||
|
* and disabled by default on Android
|
||||||
|
* for Searchbar. The autocapitalize type on HTMLElement
|
||||||
|
* requires that it be a string and never undefined.
|
||||||
|
* However, setting it to a string value would be a breaking change
|
||||||
|
* in behavior, so we use "!" to tell TypeScript that this property
|
||||||
|
* is always defined so we can rely on the browser defaults. Browsers
|
||||||
|
* will automatically set a default value if the developer does not set one.
|
||||||
|
*
|
||||||
|
* In the future, this property will default to "off" to align with
|
||||||
|
* Input and Textarea, and the "!" will not be needed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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"`.
|
||||||
|
*/
|
||||||
|
@Prop() autocapitalize!: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the input's autocomplete property.
|
* Set the input's autocomplete property.
|
||||||
*/
|
*/
|
||||||
@ -112,6 +160,16 @@ export class Searchbar implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
|
@Prop() enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This attribute specifies the maximum number of characters that the user can enter.
|
||||||
|
*/
|
||||||
|
@Prop() maxlength?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This attribute specifies the minimum number of characters that the user can enter.
|
||||||
|
*/
|
||||||
|
@Prop() minlength?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If used in a form, set the name of the control, which is submitted with the form data.
|
* If used in a form, set the name of the control, which is submitted with the form data.
|
||||||
*/
|
*/
|
||||||
@ -232,6 +290,12 @@ export class Searchbar implements ComponentInterface {
|
|||||||
this.emitStyle();
|
this.emitStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillLoad() {
|
||||||
|
this.inheritedAttributes = {
|
||||||
|
...inheritAttributes(this.el, ['lang', 'dir']),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidLoad() {
|
componentDidLoad() {
|
||||||
this.originalIonInput = this.ionInput;
|
this.originalIonInput = this.ionInput;
|
||||||
this.positionElements();
|
this.positionElements();
|
||||||
@ -614,12 +678,16 @@ export class Searchbar implements ComponentInterface {
|
|||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
onBlur={this.onBlur}
|
onBlur={this.onBlur}
|
||||||
onFocus={this.onFocus}
|
onFocus={this.onFocus}
|
||||||
|
minLength={this.minlength}
|
||||||
|
maxLength={this.maxlength}
|
||||||
placeholder={this.placeholder}
|
placeholder={this.placeholder}
|
||||||
type={this.type}
|
type={this.type}
|
||||||
value={this.getValue()}
|
value={this.getValue()}
|
||||||
|
autoCapitalize={this.autocapitalize}
|
||||||
autoComplete={this.autocomplete}
|
autoComplete={this.autocomplete}
|
||||||
autoCorrect={this.autocorrect}
|
autoCorrect={this.autocorrect}
|
||||||
spellcheck={this.spellcheck}
|
spellcheck={this.spellcheck}
|
||||||
|
{...this.inheritedAttributes}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{mode === 'md' && cancelButton}
|
{mode === 'md' && cancelButton}
|
||||||
|
@ -3,13 +3,37 @@ import { newSpecPage } from '@stencil/core/testing';
|
|||||||
import { Searchbar } from '../searchbar';
|
import { Searchbar } from '../searchbar';
|
||||||
|
|
||||||
describe('searchbar: rendering', () => {
|
describe('searchbar: rendering', () => {
|
||||||
it('should inherit attributes', async () => {
|
it('should inherit properties on load', async () => {
|
||||||
const page = await newSpecPage({
|
const page = await newSpecPage({
|
||||||
components: [Searchbar],
|
components: [Searchbar],
|
||||||
html: '<ion-searchbar name="search"></ion-searchbar>',
|
html: '<ion-searchbar autocapitalize="off" maxlength="4" minlength="2" name="search"></ion-searchbar>',
|
||||||
});
|
});
|
||||||
|
|
||||||
const nativeEl = page.body.querySelector('ion-searchbar input')!;
|
const nativeEl = page.body.querySelector('ion-searchbar input')!;
|
||||||
expect(nativeEl.getAttribute('name')).toBe('search');
|
expect(nativeEl.getAttribute('name')).toBe('search');
|
||||||
|
expect(nativeEl.getAttribute('maxlength')).toBe('4');
|
||||||
|
expect(nativeEl.getAttribute('minlength')).toBe('2');
|
||||||
|
expect(nativeEl.getAttribute('autocapitalize')).toBe('off');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inherit watched attributes', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Searchbar],
|
||||||
|
html: '<ion-searchbar dir="ltr" lang="en-US"></ion-searchbar>',
|
||||||
|
});
|
||||||
|
|
||||||
|
const searchbarEl = page.body.querySelector('ion-searchbar')!;
|
||||||
|
const nativeEl = searchbarEl.querySelector('input')!;
|
||||||
|
|
||||||
|
expect(nativeEl.getAttribute('lang')).toBe('en-US');
|
||||||
|
expect(nativeEl.getAttribute('dir')).toBe('ltr');
|
||||||
|
|
||||||
|
searchbarEl.setAttribute('lang', 'es-ES');
|
||||||
|
searchbarEl.setAttribute('dir', 'rtl');
|
||||||
|
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
expect(nativeEl.getAttribute('lang')).toBe('es-ES');
|
||||||
|
expect(nativeEl.getAttribute('dir')).toBe('rtl');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@ interface HandlerRegister {
|
|||||||
* moment this file is evaluated which could be
|
* moment this file is evaluated which could be
|
||||||
* before the config is set.
|
* before the config is set.
|
||||||
*/
|
*/
|
||||||
export const shoudUseCloseWatcher = () =>
|
export const shouldUseCloseWatcher = () =>
|
||||||
config.get('experimentalCloseWatcher', false) && win !== undefined && 'CloseWatcher' in win;
|
config.get('experimentalCloseWatcher', false) && win !== undefined && 'CloseWatcher' in win;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,7 +109,7 @@ export const startHardwareBackButton = () => {
|
|||||||
* backbutton event otherwise we may get duplicate
|
* backbutton event otherwise we may get duplicate
|
||||||
* events firing.
|
* events firing.
|
||||||
*/
|
*/
|
||||||
if (shoudUseCloseWatcher()) {
|
if (shouldUseCloseWatcher()) {
|
||||||
let watcher: CloseWatcher | undefined;
|
let watcher: CloseWatcher | undefined;
|
||||||
|
|
||||||
const configureWatcher = () => {
|
const configureWatcher = () => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { doc } from '@utils/browser';
|
import { doc } from '@utils/browser';
|
||||||
import { focusFirstDescendant, focusLastDescendant, focusableQueryString } from '@utils/focus-trap';
|
import { focusFirstDescendant, focusLastDescendant, focusableQueryString } from '@utils/focus-trap';
|
||||||
import type { BackButtonEvent } from '@utils/hardware-back-button';
|
import type { BackButtonEvent } from '@utils/hardware-back-button';
|
||||||
import { shoudUseCloseWatcher } from '@utils/hardware-back-button';
|
import { shouldUseCloseWatcher } from '@utils/hardware-back-button';
|
||||||
|
|
||||||
import { config } from '../global/config';
|
import { config } from '../global/config';
|
||||||
import { getIonMode } from '../global/ionic-global';
|
import { getIonMode } from '../global/ionic-global';
|
||||||
@ -398,7 +398,7 @@ const connectListeners = (doc: Document) => {
|
|||||||
* this behavior will be handled via the ionBackButton
|
* this behavior will be handled via the ionBackButton
|
||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
if (!shoudUseCloseWatcher()) {
|
if (!shouldUseCloseWatcher()) {
|
||||||
doc.addEventListener('keydown', (ev) => {
|
doc.addEventListener('keydown', (ev) => {
|
||||||
if (ev.key === 'Escape') {
|
if (ev.key === 'Escape') {
|
||||||
const lastOverlay = getPresentedOverlay(doc);
|
const lastOverlay = getPresentedOverlay(doc);
|
||||||
@ -514,15 +514,7 @@ export const present = async <OverlayPresentOptions>(
|
|||||||
|
|
||||||
document.body.classList.add(BACKDROP_NO_SCROLL);
|
document.body.classList.add(BACKDROP_NO_SCROLL);
|
||||||
|
|
||||||
/**
|
hideOverlaysFromScreenReaders(overlay.el);
|
||||||
* Hide all other overlays from screen readers so only this one
|
|
||||||
* can be read. Note that presenting an overlay always makes
|
|
||||||
* it the topmost one.
|
|
||||||
*/
|
|
||||||
if (doc !== undefined) {
|
|
||||||
const presentedOverlays = getPresentedOverlays(doc);
|
|
||||||
presentedOverlays.forEach((o) => o.setAttribute('aria-hidden', 'true'));
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay.presented = true;
|
overlay.presented = true;
|
||||||
overlay.willPresent.emit();
|
overlay.willPresent.emit();
|
||||||
@ -699,13 +691,7 @@ export const dismiss = async <OverlayDismissOptions>(
|
|||||||
|
|
||||||
overlay.el.remove();
|
overlay.el.remove();
|
||||||
|
|
||||||
/**
|
revealOverlaysToScreenReaders();
|
||||||
* If there are other overlays presented, unhide the new
|
|
||||||
* topmost one from screen readers.
|
|
||||||
*/
|
|
||||||
if (doc !== undefined) {
|
|
||||||
getPresentedOverlay(doc)?.removeAttribute('aria-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -942,3 +928,65 @@ export const createTriggerController = () => {
|
|||||||
removeClickListener,
|
removeClickListener,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that underlying overlays have aria-hidden if necessary so that screen readers
|
||||||
|
* cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
|
||||||
|
* events here because those events do not fire when the screen readers moves to a non-focusable
|
||||||
|
* element such as text.
|
||||||
|
* Without this logic screen readers would be able to move focus outside of the top focus-trapped overlay.
|
||||||
|
*
|
||||||
|
* @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
|
||||||
|
* fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
|
||||||
|
*/
|
||||||
|
const hideOverlaysFromScreenReaders = (newTopMostOverlay: HTMLIonOverlayElement) => {
|
||||||
|
if (doc === undefined) return;
|
||||||
|
|
||||||
|
const overlays = getPresentedOverlays(doc);
|
||||||
|
|
||||||
|
for (let i = overlays.length - 1; i >= 0; i--) {
|
||||||
|
const presentedOverlay = overlays[i];
|
||||||
|
const nextPresentedOverlay = overlays[i + 1] ?? newTopMostOverlay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If next overlay has aria-hidden then all remaining overlays will have it too.
|
||||||
|
* Or, if the next overlay is a Toast that does not have aria-hidden then current overlay
|
||||||
|
* should not have aria-hidden either so focus can remain in the current overlay.
|
||||||
|
*/
|
||||||
|
if (nextPresentedOverlay.hasAttribute('aria-hidden') || nextPresentedOverlay.tagName !== 'ION-TOAST') {
|
||||||
|
presentedOverlay.setAttribute('aria-hidden', 'true');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When dismissing an overlay we need to reveal the new top-most overlay to screen readers.
|
||||||
|
* If the top-most overlay is a Toast we potentially need to reveal more overlays since
|
||||||
|
* focus is never automatically moved to the Toast.
|
||||||
|
*/
|
||||||
|
const revealOverlaysToScreenReaders = () => {
|
||||||
|
if (doc === undefined) return;
|
||||||
|
|
||||||
|
const overlays = getPresentedOverlays(doc);
|
||||||
|
|
||||||
|
for (let i = overlays.length - 1; i >= 0; i--) {
|
||||||
|
const currentOverlay = overlays[i];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current we are looking at is a Toast then we can remove aria-hidden.
|
||||||
|
* However, we potentially need to keep looking at the overlay stack because there
|
||||||
|
* could be more Toasts underneath. Additionally, we need to unhide the closest non-Toast
|
||||||
|
* overlay too so focus can move there since focus is never automatically moved to the Toast.
|
||||||
|
*/
|
||||||
|
currentOverlay.removeAttribute('aria-hidden');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we found a non-Toast element then we can just remove aria-hidden and stop searching entirely
|
||||||
|
* since this overlay should always receive focus. As a result, all underlying overlays should still
|
||||||
|
* be hidden from screen readers.
|
||||||
|
*/
|
||||||
|
if (currentOverlay.tagName !== 'ION-TOAST') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { newSpecPage } from '@stencil/core/testing';
|
import { newSpecPage } from '@stencil/core/testing';
|
||||||
|
|
||||||
import { Modal } from '../../../components/modal/modal';
|
import { Modal } from '../../../components/modal/modal';
|
||||||
|
import { Toast } from '../../../components/toast/toast';
|
||||||
import { Nav } from '../../../components/nav/nav';
|
import { Nav } from '../../../components/nav/nav';
|
||||||
import { RouterOutlet } from '../../../components/router-outlet/router-outlet';
|
import { RouterOutlet } from '../../../components/router-outlet/router-outlet';
|
||||||
import { setRootAriaHidden } from '../../overlays';
|
import { setRootAriaHidden } from '../../overlays';
|
||||||
@ -193,4 +194,70 @@ describe('aria-hidden on individual overlays', () => {
|
|||||||
await modalOne.present();
|
await modalOne.present();
|
||||||
expect(modalOne.hasAttribute('aria-hidden')).toEqual(false);
|
expect(modalOne.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not hide previous overlay if top-most overlay is toast', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Modal, Toast],
|
||||||
|
html: `
|
||||||
|
<ion-modal id="m-one"></ion-modal>
|
||||||
|
<ion-modal id="m-two"></ion-modal>
|
||||||
|
<ion-toast id="t-one"></ion-toast>
|
||||||
|
<ion-toast id="t-two"></ion-toast>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modalOne = page.body.querySelector<HTMLIonModalElement>('ion-modal#m-one')!;
|
||||||
|
const modalTwo = page.body.querySelector<HTMLIonModalElement>('ion-modal#m-two')!;
|
||||||
|
const toastOne = page.body.querySelector<HTMLIonModalElement>('ion-toast#t-one')!;
|
||||||
|
const toastTwo = page.body.querySelector<HTMLIonModalElement>('ion-toast#t-two')!;
|
||||||
|
|
||||||
|
await modalOne.present();
|
||||||
|
await modalTwo.present();
|
||||||
|
await toastOne.present();
|
||||||
|
await toastTwo.present();
|
||||||
|
|
||||||
|
expect(modalOne.hasAttribute('aria-hidden')).toEqual(true);
|
||||||
|
expect(modalTwo.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
expect(toastOne.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
expect(toastTwo.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
|
||||||
|
await toastTwo.dismiss();
|
||||||
|
|
||||||
|
expect(modalOne.hasAttribute('aria-hidden')).toEqual(true);
|
||||||
|
expect(modalTwo.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
expect(toastOne.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
|
||||||
|
await toastOne.dismiss();
|
||||||
|
|
||||||
|
expect(modalOne.hasAttribute('aria-hidden')).toEqual(true);
|
||||||
|
expect(modalTwo.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should hide previous overlay even with a toast that is not the top-most overlay', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Modal, Toast],
|
||||||
|
html: `
|
||||||
|
<ion-modal id="m-one"></ion-modal>
|
||||||
|
<ion-toast id="t-one"></ion-toast>
|
||||||
|
<ion-modal id="m-two"></ion-modal>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modalOne = page.body.querySelector<HTMLIonModalElement>('ion-modal#m-one')!;
|
||||||
|
const modalTwo = page.body.querySelector<HTMLIonModalElement>('ion-modal#m-two')!;
|
||||||
|
const toastOne = page.body.querySelector<HTMLIonModalElement>('ion-toast#t-one')!;
|
||||||
|
|
||||||
|
await modalOne.present();
|
||||||
|
await toastOne.present();
|
||||||
|
await modalTwo.present();
|
||||||
|
|
||||||
|
expect(modalOne.hasAttribute('aria-hidden')).toEqual(true);
|
||||||
|
expect(toastOne.hasAttribute('aria-hidden')).toEqual(true);
|
||||||
|
expect(modalTwo.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
|
||||||
|
await modalTwo.dismiss();
|
||||||
|
|
||||||
|
expect(modalOne.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
expect(toastOne.hasAttribute('aria-hidden')).toEqual(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/docs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/docs
|
**Note:** Version bump only for package @ionic/docs
|
||||||
@ -11,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/docs
|
**Note:** Version bump only for package @ionic/docs
|
||||||
|
|
||||||
@ -27,6 +35,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/docs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/docs
|
**Note:** Version bump only for package @ionic/docs
|
||||||
|
@ -3,8 +3,33 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular-server
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
|
||||||
|
|
||||||
@ -22,14 +47,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular-server
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular-server
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
@ -3,6 +3,29 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **datetime:** formatOptions property for Datetime ([#29065](https://github.com/ionic-team/ionic-framework/issues/29065)) ([7cdbc1b](https://github.com/ionic-team/ionic-framework/commit/7cdbc1b5ad004e17a7c51363653e0e67f50e6860))
|
||||||
|
* **searchbar:** autocapitalize, dir, lang, maxlength, and minlength are inherited to native input ([#29098](https://github.com/ionic-team/ionic-framework/issues/29098)) ([a0a77f7](https://github.com/ionic-team/ionic-framework/commit/a0a77f799df0732d9f7182f15866035a3ce5a1eb)), closes [#27606](https://github.com/ionic-team/ionic-framework/issues/27606)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **angular:** add ionNavWillChange and ionNavDidChange types for nav ([#29122](https://github.com/ionic-team/ionic-framework/issues/29122)) ([85b9d5c](https://github.com/ionic-team/ionic-framework/commit/85b9d5c35f626ffc273d220549b0126ddc1f7e4b)), closes [#29114](https://github.com/ionic-team/ionic-framework/issues/29114)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular
|
**Note:** Version bump only for package @ionic/angular
|
||||||
@ -11,6 +34,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/angular
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
|
||||||
@ -52,14 +83,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular
|
**Note:** Version bump only for package @ionic/angular
|
||||||
|
@ -635,7 +635,7 @@ Set `scrollEvents` to `true` to enable.
|
|||||||
|
|
||||||
|
|
||||||
@ProxyCmp({
|
@ProxyCmp({
|
||||||
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
|
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'formatOptions', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
|
||||||
methods: ['confirm', 'reset', 'cancel']
|
methods: ['confirm', 'reset', 'cancel']
|
||||||
})
|
})
|
||||||
@Component({
|
@Component({
|
||||||
@ -643,7 +643,7 @@ Set `scrollEvents` to `true` to enable.
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
template: '<ng-content></ng-content>',
|
template: '<ng-content></ng-content>',
|
||||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||||
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
|
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'formatOptions', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
|
||||||
})
|
})
|
||||||
export class IonDatetime {
|
export class IonDatetime {
|
||||||
protected el: HTMLElement;
|
protected el: HTMLElement;
|
||||||
@ -1863,7 +1863,7 @@ export declare interface IonRow extends Components.IonRow {}
|
|||||||
|
|
||||||
|
|
||||||
@ProxyCmp({
|
@ProxyCmp({
|
||||||
inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'mode', 'name', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
|
inputs: ['animated', 'autocapitalize', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'maxlength', 'minlength', 'mode', 'name', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
|
||||||
methods: ['setFocus', 'getInputElement']
|
methods: ['setFocus', 'getInputElement']
|
||||||
})
|
})
|
||||||
@Component({
|
@Component({
|
||||||
@ -1871,7 +1871,7 @@ export declare interface IonRow extends Components.IonRow {}
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
template: '<ng-content></ng-content>',
|
template: '<ng-content></ng-content>',
|
||||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||||
inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'mode', 'name', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
|
inputs: ['animated', 'autocapitalize', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'maxlength', 'minlength', 'mode', 'name', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
|
||||||
})
|
})
|
||||||
export class IonSearchbar {
|
export class IonSearchbar {
|
||||||
protected el: HTMLElement;
|
protected el: HTMLElement;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/react-router
|
**Note:** Version bump only for package @ionic/react-router
|
||||||
|
|
||||||
@ -11,7 +11,16 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/react-router
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/react-router
|
**Note:** Version bump only for package @ionic/react-router
|
||||||
|
|
||||||
@ -27,6 +36,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/react-router
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/react-router
|
**Note:** Version bump only for package @ionic/react-router
|
||||||
|
12
packages/react-router/package-lock.json
generated
12
packages/react-router/package-lock.json
generated
@ -667,9 +667,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@stencil/core": {
|
"node_modules/@stencil/core": {
|
||||||
"version": "4.12.5",
|
"version": "4.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.6.tgz",
|
||||||
"integrity": "sha512-vSyFjY7XSEx0ufa9SebOd437CvnneaTXlCpuGDhjUDxAjGBlu6ie5qHyubobVGBth//aErc6wZPHc6W75Vp3iQ==",
|
"integrity": "sha512-15JO2TdaxGVKNdLZb/2TtDa+juj3XGD/V0y/disgdzYYSnajgSh06nwODfdHz9eTUh1Hisz+KIo857I1rCZrfg==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"stencil": "bin/stencil"
|
"stencil": "bin/stencil"
|
||||||
},
|
},
|
||||||
@ -4297,9 +4297,9 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@stencil/core": {
|
"@stencil/core": {
|
||||||
"version": "4.12.5",
|
"version": "4.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.6.tgz",
|
||||||
"integrity": "sha512-vSyFjY7XSEx0ufa9SebOd437CvnneaTXlCpuGDhjUDxAjGBlu6ie5qHyubobVGBth//aErc6wZPHc6W75Vp3iQ=="
|
"integrity": "sha512-15JO2TdaxGVKNdLZb/2TtDa+juj3XGD/V0y/disgdzYYSnajgSh06nwODfdHz9eTUh1Hisz+KIo857I1rCZrfg=="
|
||||||
},
|
},
|
||||||
"@types/estree": {
|
"@types/estree": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/react
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/react
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/react
|
**Note:** Version bump only for package @ionic/react
|
||||||
@ -11,6 +27,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/react
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
|
||||||
@ -22,14 +46,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/react
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/react
|
**Note:** Version bump only for package @ionic/react
|
||||||
|
@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/vue-router
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/vue-router
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/vue-router
|
**Note:** Version bump only for package @ionic/vue-router
|
||||||
@ -11,7 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/vue-router
|
**Note:** Version bump only for package @ionic/vue-router
|
||||||
|
|
||||||
@ -19,7 +35,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/vue-router
|
**Note:** Version bump only for package @ionic/vue-router
|
||||||
|
|
||||||
|
12
packages/vue-router/package-lock.json
generated
12
packages/vue-router/package-lock.json
generated
@ -1508,9 +1508,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@stencil/core": {
|
"node_modules/@stencil/core": {
|
||||||
"version": "4.12.5",
|
"version": "4.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.6.tgz",
|
||||||
"integrity": "sha512-vSyFjY7XSEx0ufa9SebOd437CvnneaTXlCpuGDhjUDxAjGBlu6ie5qHyubobVGBth//aErc6wZPHc6W75Vp3iQ==",
|
"integrity": "sha512-15JO2TdaxGVKNdLZb/2TtDa+juj3XGD/V0y/disgdzYYSnajgSh06nwODfdHz9eTUh1Hisz+KIo857I1rCZrfg==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"stencil": "bin/stencil"
|
"stencil": "bin/stencil"
|
||||||
},
|
},
|
||||||
@ -8461,9 +8461,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@stencil/core": {
|
"@stencil/core": {
|
||||||
"version": "4.12.5",
|
"version": "4.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.6.tgz",
|
||||||
"integrity": "sha512-vSyFjY7XSEx0ufa9SebOd437CvnneaTXlCpuGDhjUDxAjGBlu6ie5qHyubobVGBth//aErc6wZPHc6W75Vp3iQ=="
|
"integrity": "sha512-15JO2TdaxGVKNdLZb/2TtDa+juj3XGD/V0y/disgdzYYSnajgSh06nwODfdHz9eTUh1Hisz+KIo857I1rCZrfg=="
|
||||||
},
|
},
|
||||||
"@tootallnate/once": {
|
"@tootallnate/once": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
@ -3,6 +3,27 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
|
||||||
|
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **datetime:** formatOptions property for Datetime ([#29065](https://github.com/ionic-team/ionic-framework/issues/29065)) ([7cdbc1b](https://github.com/ionic-team/ionic-framework/commit/7cdbc1b5ad004e17a7c51363653e0e67f50e6860))
|
||||||
|
* **searchbar:** autocapitalize, dir, lang, maxlength, and minlength are inherited to native input ([#29098](https://github.com/ionic-team/ionic-framework/issues/29098)) ([a0a77f7](https://github.com/ionic-team/ionic-framework/commit/a0a77f799df0732d9f7182f15866035a3ce5a1eb)), closes [#27606](https://github.com/ionic-team/ionic-framework/issues/27606)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/vue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
# [8.0.0-beta.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2024-03-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/vue
|
**Note:** Version bump only for package @ionic/vue
|
||||||
@ -11,6 +32,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/vue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
# [8.0.0-beta.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v8.0.0-beta.0) (2024-02-28)
|
||||||
|
|
||||||
|
|
||||||
@ -41,14 +70,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/vue
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/vue
|
**Note:** Version bump only for package @ionic/vue
|
||||||
|
@ -275,6 +275,7 @@ export const IonDatetime = /*@__PURE__*/ defineContainer<JSX.IonDatetime, JSX.Io
|
|||||||
'color',
|
'color',
|
||||||
'name',
|
'name',
|
||||||
'disabled',
|
'disabled',
|
||||||
|
'formatOptions',
|
||||||
'readonly',
|
'readonly',
|
||||||
'isDateEnabled',
|
'isDateEnabled',
|
||||||
'min',
|
'min',
|
||||||
@ -686,6 +687,7 @@ export const IonRow = /*@__PURE__*/ defineContainer<JSX.IonRow>('ion-row', defin
|
|||||||
export const IonSearchbar = /*@__PURE__*/ defineContainer<JSX.IonSearchbar, JSX.IonSearchbar["value"]>('ion-searchbar', defineIonSearchbar, [
|
export const IonSearchbar = /*@__PURE__*/ defineContainer<JSX.IonSearchbar, JSX.IonSearchbar["value"]>('ion-searchbar', defineIonSearchbar, [
|
||||||
'color',
|
'color',
|
||||||
'animated',
|
'animated',
|
||||||
|
'autocapitalize',
|
||||||
'autocomplete',
|
'autocomplete',
|
||||||
'autocorrect',
|
'autocorrect',
|
||||||
'cancelButtonIcon',
|
'cancelButtonIcon',
|
||||||
@ -695,6 +697,8 @@ export const IonSearchbar = /*@__PURE__*/ defineContainer<JSX.IonSearchbar, JSX.
|
|||||||
'disabled',
|
'disabled',
|
||||||
'inputmode',
|
'inputmode',
|
||||||
'enterkeyhint',
|
'enterkeyhint',
|
||||||
|
'maxlength',
|
||||||
|
'minlength',
|
||||||
'name',
|
'name',
|
||||||
'placeholder',
|
'placeholder',
|
||||||
'searchIcon',
|
'searchIcon',
|
||||||
|
Reference in New Issue
Block a user