merge release-6.1.10
Release 6.1.10
16
CHANGELOG.md
@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.1.10](https://github.com/ionic-team/ionic-framework/compare/v6.1.9...v6.1.10) (2022-06-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** router compatibility with Angular 12/13 ([#25456](https://github.com/ionic-team/ionic-framework/issues/25456)) ([7b105a3](https://github.com/ionic-team/ionic-framework/commit/7b105a3471e5bc588ba63f820b707e131c878b6f)), closes [#25448](https://github.com/ionic-team/ionic-framework/issues/25448)
|
||||
* **fab-button:** improve ripple effect behavior on click ([#25413](https://github.com/ionic-team/ionic-framework/issues/25413)) ([efdaf90](https://github.com/ionic-team/ionic-framework/commit/efdaf90c5a767211e0034bab7cce5bd463ff5aa0)), closes [#21772](https://github.com/ionic-team/ionic-framework/issues/21772)
|
||||
* **modal:** backdrop animation when backdropBreakpoint is 1 ([#25430](https://github.com/ionic-team/ionic-framework/issues/25430)) ([c10df52](https://github.com/ionic-team/ionic-framework/commit/c10df52f39c527dd7e03176c56a2e6cb0ebe455f)), closes [#25402](https://github.com/ionic-team/ionic-framework/issues/25402)
|
||||
* **modal:** status bar color now correct with sheet modal ([#25424](https://github.com/ionic-team/ionic-framework/issues/25424)) ([377c4f5](https://github.com/ionic-team/ionic-framework/commit/377c4f597b972818d90132017d50c33074ddadab)), closes [#20501](https://github.com/ionic-team/ionic-framework/issues/20501)
|
||||
* **picker-column-internal:** switching off an input mode column preserves scroll ([#25467](https://github.com/ionic-team/ionic-framework/issues/25467)) ([989429d](https://github.com/ionic-team/ionic-framework/commit/989429d65cf57ef8fb69854639f8eac1a12369bc))
|
||||
* **popover:** ensure popover does not go offscreen when adjusting top position ([#25350](https://github.com/ionic-team/ionic-framework/issues/25350)) ([6926538](https://github.com/ionic-team/ionic-framework/commit/692653842b43b5e36c51163f8261fde3b5bea40d)), closes [#25349](https://github.com/ionic-team/ionic-framework/issues/25349)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.1.9](https://github.com/ionic-team/ionic-framework/compare/v6.1.8...v6.1.9) (2022-06-08)
|
||||
|
||||
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.1.10](https://github.com/ionic-team/ionic/compare/v6.1.9...v6.1.10) (2022-06-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** router compatibility with Angular 12/13 ([#25456](https://github.com/ionic-team/ionic/issues/25456)) ([7b105a3](https://github.com/ionic-team/ionic/commit/7b105a3471e5bc588ba63f820b707e131c878b6f)), closes [#25448](https://github.com/ionic-team/ionic/issues/25448)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.1.9](https://github.com/ionic-team/ionic/compare/v6.1.8...v6.1.9) (2022-06-08)
|
||||
|
||||
|
||||
|
18
angular/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.1.9",
|
||||
"version": "6.1.10",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.1.9",
|
||||
"version": "6.1.10",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.1.9",
|
||||
"@ionic/core": "^6.1.10",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
@ -1023,9 +1023,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.9.tgz",
|
||||
"integrity": "sha512-EaClsiGB/E9wPkujnrMZ71BLVcA8t6DBZu+caJMmqPLF/64S37CiyfrrMbL1UnxDWP2TXsPFH3seWl6Ek/W1bw==",
|
||||
"version": "6.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.10.tgz",
|
||||
"integrity": "sha512-QmQvIe+IklQhNhbq438I3eCnL6XjfTxrgO1+paOdGNKk3R3o4mqJmV0YYT5r9iwnieHgDxKbo3ovs9UnTXhI7g==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -7939,9 +7939,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.9.tgz",
|
||||
"integrity": "sha512-EaClsiGB/E9wPkujnrMZ71BLVcA8t6DBZu+caJMmqPLF/64S37CiyfrrMbL1UnxDWP2TXsPFH3seWl6Ek/W1bw==",
|
||||
"version": "6.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.10.tgz",
|
||||
"integrity": "sha512-QmQvIe+IklQhNhbq438I3eCnL6XjfTxrgO1+paOdGNKk3R3o4mqJmV0YYT5r9iwnieHgDxKbo3ovs9UnTXhI7g==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.1.9",
|
||||
"version": "6.1.10",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -44,7 +44,7 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.1.9",
|
||||
"@ionic/core": "^6.1.10",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
|
@ -89,6 +89,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
private config: Config,
|
||||
private navCtrl: NavController,
|
||||
@Optional() private environmentInjector: EnvironmentInjector,
|
||||
@Optional() private componentFactoryResolver: ComponentFactoryResolver,
|
||||
commonLocation: Location,
|
||||
elementRef: ElementRef,
|
||||
router: Router,
|
||||
@ -243,6 +244,12 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
|
||||
const injector = new OutletInjector(activatedRouteProxy, childContexts, this.location.injector);
|
||||
|
||||
/**
|
||||
* The resolver is not always provided and is required in < Angular 14.
|
||||
* Fallback to the class-level provider when the resolver is not set.
|
||||
*/
|
||||
resolverOrInjector = resolverOrInjector || this.componentFactoryResolver;
|
||||
|
||||
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
|
||||
// Backwards compatibility for Angular 13 and lower
|
||||
const factory = resolverOrInjector.resolveComponentFactory(component);
|
||||
|
17730
angular/test/test-app/package-lock.json
generated
@ -31,7 +31,7 @@
|
||||
"@angular/router": "^13.1.3",
|
||||
"@ionic/angular": "^6.0.12",
|
||||
"@ionic/angular-server": "^6.0.12",
|
||||
"@nguniversal/express-engine": "^12.1.1",
|
||||
"@nguniversal/express-engine": "^13.1.1",
|
||||
"angular-in-memory-web-api": "^0.11.0",
|
||||
"core-js": "^2.6.11",
|
||||
"express": "^4.15.2",
|
||||
@ -60,9 +60,9 @@
|
||||
"eslint": "^7.26.0",
|
||||
"ts-loader": "^6.2.2",
|
||||
"ts-node": "^8.3.0",
|
||||
"typescript": "^4.5.5",
|
||||
"typescript": "~4.6.0",
|
||||
"wait-on": "^5.2.1",
|
||||
"webpack": "^5.61.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
"webpack-cli": "^4.9.2"
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
extends: ['@commitlint/config-conventional']
|
||||
}
|
11
core/.prettierrc.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
...require('@ionic/prettier-config'),
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.scss'],
|
||||
options: {
|
||||
singleQuote: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.1.10](https://github.com/ionic-team/ionic/compare/v6.1.9...v6.1.10) (2022-06-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **fab-button:** improve ripple effect behavior on click ([#25413](https://github.com/ionic-team/ionic/issues/25413)) ([efdaf90](https://github.com/ionic-team/ionic/commit/efdaf90c5a767211e0034bab7cce5bd463ff5aa0)), closes [#21772](https://github.com/ionic-team/ionic/issues/21772)
|
||||
* **modal:** backdrop animation when backdropBreakpoint is 1 ([#25430](https://github.com/ionic-team/ionic/issues/25430)) ([c10df52](https://github.com/ionic-team/ionic/commit/c10df52f39c527dd7e03176c56a2e6cb0ebe455f)), closes [#25402](https://github.com/ionic-team/ionic/issues/25402)
|
||||
* **modal:** status bar color now correct with sheet modal ([#25424](https://github.com/ionic-team/ionic/issues/25424)) ([377c4f5](https://github.com/ionic-team/ionic/commit/377c4f597b972818d90132017d50c33074ddadab)), closes [#20501](https://github.com/ionic-team/ionic/issues/20501)
|
||||
* **picker-column-internal:** switching off an input mode column preserves scroll ([#25467](https://github.com/ionic-team/ionic/issues/25467)) ([989429d](https://github.com/ionic-team/ionic/commit/989429d65cf57ef8fb69854639f8eac1a12369bc))
|
||||
* **popover:** ensure popover does not go offscreen when adjusting top position ([#25350](https://github.com/ionic-team/ionic/issues/25350)) ([6926538](https://github.com/ionic-team/ionic/commit/692653842b43b5e36c51163f8261fde3b5bea40d)), closes [#25349](https://github.com/ionic-team/ionic/issues/25349)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.1.9](https://github.com/ionic-team/ionic/compare/v6.1.8...v6.1.9) (2022-06-08)
|
||||
|
||||
|
||||
|
4769
core/package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "6.1.9",
|
||||
"version": "6.1.10",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -46,7 +46,7 @@
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.4.0",
|
||||
"@stencil/react-output-target": "^0.2.1",
|
||||
"@stencil/sass": "1.3.2",
|
||||
"@stencil/sass": "^1.5.2",
|
||||
"@stencil/vue-output-target": "^0.6.0",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/node": "^14.6.0",
|
||||
@ -62,7 +62,6 @@
|
||||
"fs-extra": "^9.0.1",
|
||||
"jest": "^26.4.1",
|
||||
"jest-cli": "^26.4.1",
|
||||
"np": "^6.4.0",
|
||||
"pixelmatch": "4.0.2",
|
||||
"prettier": "^2.6.1",
|
||||
"puppeteer": "^10.4.0",
|
||||
@ -117,6 +116,5 @@
|
||||
"homepage": "https://ionicframework.com/",
|
||||
"jest": {
|
||||
"preset": "@stencil/core/testing"
|
||||
},
|
||||
"prettier": "@ionic/prettier-config"
|
||||
}
|
||||
}
|
||||
|
20
core/src/components.d.ts
vendored
@ -847,6 +847,10 @@ export namespace Components {
|
||||
* Where to align the fab horizontally in the viewport.
|
||||
*/
|
||||
"horizontal"?: 'start' | 'end' | 'center';
|
||||
/**
|
||||
* Opens/Closes the FAB list container.
|
||||
*/
|
||||
"toggle": () => Promise<void>;
|
||||
/**
|
||||
* Where to align the fab vertically in the viewport.
|
||||
*/
|
||||
@ -1596,7 +1600,7 @@ export namespace Components {
|
||||
*/
|
||||
"setCurrentBreakpoint": (breakpoint: number) => Promise<void>;
|
||||
/**
|
||||
* If `true`, a backdrop will be displayed behind the modal.
|
||||
* If `true`, a backdrop will be displayed behind the modal. This property controls whether or not the backdrop darkens the screen when the modal is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
||||
*/
|
||||
"showBackdrop": boolean;
|
||||
/**
|
||||
@ -1615,7 +1619,7 @@ export namespace Components {
|
||||
*/
|
||||
"animated": boolean;
|
||||
/**
|
||||
* By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimateBuilder` functions.
|
||||
* By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimationBuilder` functions.
|
||||
*/
|
||||
"animation"?: AnimationBuilder;
|
||||
/**
|
||||
@ -1962,7 +1966,7 @@ export namespace Components {
|
||||
*/
|
||||
"reference": PositionReference;
|
||||
/**
|
||||
* If `true`, a backdrop will be displayed behind the popover.
|
||||
* If `true`, a backdrop will be displayed behind the popover. This property controls whether or not the backdrop darkens the screen when the popover is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
||||
*/
|
||||
"showBackdrop": boolean;
|
||||
/**
|
||||
@ -2276,7 +2280,7 @@ export namespace Components {
|
||||
*/
|
||||
"animated": boolean;
|
||||
/**
|
||||
* This property allows to create custom transition using AnimateBuilder functions.
|
||||
* This property allows to create custom transition using AnimationBuilder functions.
|
||||
*/
|
||||
"animation"?: AnimationBuilder;
|
||||
"commit": (enteringEl: HTMLElement, leavingEl: HTMLElement | undefined, opts?: RouterOutletOptions | undefined) => Promise<boolean>;
|
||||
@ -5524,7 +5528,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"presentingElement"?: HTMLElement;
|
||||
/**
|
||||
* If `true`, a backdrop will be displayed behind the modal.
|
||||
* If `true`, a backdrop will be displayed behind the modal. This property controls whether or not the backdrop darkens the screen when the modal is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
||||
*/
|
||||
"showBackdrop"?: boolean;
|
||||
/**
|
||||
@ -5543,7 +5547,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"animated"?: boolean;
|
||||
/**
|
||||
* By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimateBuilder` functions.
|
||||
* By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimationBuilder` functions.
|
||||
*/
|
||||
"animation"?: AnimationBuilder;
|
||||
"delegate"?: FrameworkDelegate;
|
||||
@ -5812,7 +5816,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"reference"?: PositionReference;
|
||||
/**
|
||||
* If `true`, a backdrop will be displayed behind the popover.
|
||||
* If `true`, a backdrop will be displayed behind the popover. This property controls whether or not the backdrop darkens the screen when the popover is presented. It does not control whether or not the backdrop is active or present in the DOM.
|
||||
*/
|
||||
"showBackdrop"?: boolean;
|
||||
/**
|
||||
@ -6160,7 +6164,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"animated"?: boolean;
|
||||
/**
|
||||
* This property allows to create custom transition using AnimateBuilder functions.
|
||||
* This property allows to create custom transition using AnimationBuilder functions.
|
||||
*/
|
||||
"animation"?: AnimationBuilder;
|
||||
"delegate"?: FrameworkDelegate;
|
||||
|
@ -1,3 +1,4 @@
|
||||
@use "sass:math";
|
||||
@import "../../themes/ionic.globals.ios";
|
||||
@import "../item/item.ios.vars";
|
||||
|
||||
@ -275,16 +276,16 @@ $alert-ios-checkbox-background-color-off: $item-ios-background !de
|
||||
$alert-ios-checkbox-background-color-on: ion-color(primary, base) !default;
|
||||
|
||||
/// @prop - Top of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-top: $alert-ios-checkbox-size / 6 !default;
|
||||
$alert-ios-checkbox-icon-top: math.div($alert-ios-checkbox-size, 6) !default;
|
||||
|
||||
/// @prop - Start of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-start: ($alert-ios-checkbox-size / 3) + 1px !default;
|
||||
$alert-ios-checkbox-icon-start: math.div($alert-ios-checkbox-size, 3) + 1px !default;
|
||||
|
||||
/// @prop - Width of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-width: ($alert-ios-checkbox-size / 6) + 1px !default;
|
||||
$alert-ios-checkbox-icon-width: math.div($alert-ios-checkbox-size, 6) + 1px !default;
|
||||
|
||||
/// @prop - Height of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-height: $alert-ios-checkbox-size / 2 !default;
|
||||
$alert-ios-checkbox-icon-height: $alert-ios-checkbox-size * 0.5 !default;
|
||||
|
||||
/// @prop - Border width of the icon in the checkbox alert
|
||||
$alert-ios-checkbox-icon-border-width: $alert-ios-checkbox-border-width !default;
|
||||
|
@ -203,13 +203,13 @@ $alert-md-radio-border-color-off: $text-color-step-450 !default;
|
||||
$alert-md-radio-border-color-on: $alert-md-button-text-color !default;
|
||||
|
||||
/// @prop - Width of the icon in the alert radio
|
||||
$alert-md-radio-icon-width: $alert-md-radio-width / 2 !default;
|
||||
$alert-md-radio-icon-width: $alert-md-radio-width * 0.5 !default;
|
||||
|
||||
/// @prop - Height of the icon in the alert radio
|
||||
$alert-md-radio-icon-height: $alert-md-radio-icon-width !default;
|
||||
|
||||
/// @prop - Top of the icon in the alert radio
|
||||
$alert-md-radio-icon-top: ($alert-md-radio-width - $alert-md-radio-icon-width - $alert-md-radio-border-width * 2) / 2 !default;
|
||||
$alert-md-radio-icon-top: ($alert-md-radio-width - $alert-md-radio-icon-width - $alert-md-radio-border-width * 2) * 0.5 !default;
|
||||
|
||||
/// @prop - Start of the icon in the radio alert
|
||||
$alert-md-radio-icon-start: $alert-md-radio-icon-top !default;
|
||||
|
@ -1,3 +1,4 @@
|
||||
@use "sass:math";
|
||||
@import "../../themes/ionic.globals.ios";
|
||||
@import "../item/item.ios.vars";
|
||||
|
||||
@ -41,16 +42,16 @@ $checkbox-ios-checkmark-border-style: solid !default;
|
||||
$checkbox-ios-checkmark-border-color: ion-color(primary, contrast) !default;
|
||||
|
||||
/// @prop - Top of the checkmark in the checkbox
|
||||
$checkbox-ios-checkmark-top: $checkbox-ios-icon-size / 6 !default;
|
||||
$checkbox-ios-checkmark-top: math.div($checkbox-ios-icon-size, 6) !default;
|
||||
|
||||
/// @prop - Start of the checkmark in the checkbox
|
||||
$checkbox-ios-checkmark-start: ($checkbox-ios-icon-size / 3) + 1px !default;
|
||||
$checkbox-ios-checkmark-start: math.div($checkbox-ios-icon-size, 3) + 1px !default;
|
||||
|
||||
/// @prop - Width of the checkmark in the checkbox
|
||||
$checkbox-ios-checkmark-width: ($checkbox-ios-icon-size / 6) + 1px !default;
|
||||
$checkbox-ios-checkmark-width: math.div($checkbox-ios-icon-size, 6) + 1px !default;
|
||||
|
||||
/// @prop - Height of the checkmark in the checkbox
|
||||
$checkbox-ios-checkmark-height: $checkbox-ios-icon-size / 2 !default;
|
||||
$checkbox-ios-checkmark-height: $checkbox-ios-icon-size * 0.5 !default;
|
||||
|
||||
/// @prop - Opacity of the disabled checkbox
|
||||
$checkbox-ios-disabled-opacity: .3 !default;
|
||||
|
@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
:host .calendar-action-buttons ion-buttons {
|
||||
@include padding($datetime-ios-padding / 2, 0, 0, 0);
|
||||
@include padding($datetime-ios-padding * 0.5, 0, 0, 0);
|
||||
}
|
||||
|
||||
:host .calendar-action-buttons ion-buttons ion-button {
|
||||
@ -55,7 +55,7 @@
|
||||
// Calendar / Header / Days of Week
|
||||
// -----------------------------------
|
||||
:host .calendar-days-of-week {
|
||||
@include padding(0, $datetime-ios-padding / 2, 0, $datetime-ios-padding / 2);
|
||||
@include padding(0, $datetime-ios-padding * 0.5, 0, $datetime-ios-padding * 0.5);
|
||||
|
||||
color: $text-color-step-700;
|
||||
|
||||
@ -79,7 +79,7 @@
|
||||
* this padding a snapping point if applied
|
||||
* on .calendar-month
|
||||
*/
|
||||
@include padding($datetime-ios-padding / 2, $datetime-ios-padding / 2, $datetime-ios-padding / 2, $datetime-ios-padding / 2);
|
||||
@include padding($datetime-ios-padding * 0.5, $datetime-ios-padding * 0.5, $datetime-ios-padding * 0.5, $datetime-ios-padding * 0.5);
|
||||
|
||||
height: calc(100% - #{$datetime-ios-padding});
|
||||
}
|
||||
@ -136,7 +136,7 @@
|
||||
// Time / Header
|
||||
// -----------------------------------
|
||||
:host .datetime-time {
|
||||
@include padding($datetime-ios-padding / 2, $datetime-ios-padding, $datetime-ios-padding, $datetime-ios-padding);
|
||||
@include padding($datetime-ios-padding * 0.5, $datetime-ios-padding, $datetime-ios-padding, $datetime-ios-padding);
|
||||
|
||||
font-size: 16px;
|
||||
}
|
||||
@ -148,7 +148,7 @@
|
||||
// Footer
|
||||
// -----------------------------------
|
||||
:host .datetime-buttons {
|
||||
@include padding($datetime-ios-padding / 2, $datetime-ios-padding / 2, $datetime-ios-padding / 2, $datetime-ios-padding / 2);
|
||||
@include padding($datetime-ios-padding * 0.5, $datetime-ios-padding * 0.5, $datetime-ios-padding * 0.5, $datetime-ios-padding * 0.5);
|
||||
|
||||
border-top: $datetime-ios-border-color;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@
|
||||
// Time / Header
|
||||
// -----------------------------------
|
||||
:host .datetime-time {
|
||||
@include padding($datetime-md-padding / 2, $datetime-md-padding, $datetime-md-padding / 2, $datetime-md-padding);
|
||||
@include padding($datetime-md-padding * 0.5, $datetime-md-padding, $datetime-md-padding * 0.5, $datetime-md-padding);
|
||||
}
|
||||
|
||||
:host .time-header {
|
||||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 46 KiB |
@ -199,7 +199,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.fab-button-small) {
|
||||
@include margin(($fab-size - $fab-small-size) / 2);
|
||||
@include margin(($fab-size - $fab-small-size) * 0.5);
|
||||
|
||||
width: #{$fab-small-size};
|
||||
height: #{$fab-small-size};
|
||||
|
@ -22,6 +22,8 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
shadow: true,
|
||||
})
|
||||
export class FabButton implements ComponentInterface, AnchorInterface, ButtonInterface {
|
||||
private fab: HTMLIonFabElement | null = null;
|
||||
|
||||
@Element() el!: HTMLElement;
|
||||
|
||||
/**
|
||||
@ -119,6 +121,10 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
||||
*/
|
||||
@Event() ionBlur!: EventEmitter<void>;
|
||||
|
||||
connectedCallback() {
|
||||
this.fab = this.el.closest('ion-fab');
|
||||
}
|
||||
|
||||
private onFocus = () => {
|
||||
this.ionFocus.emit();
|
||||
};
|
||||
@ -127,6 +133,15 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
||||
this.ionBlur.emit();
|
||||
};
|
||||
|
||||
private onClick = () => {
|
||||
const { fab } = this;
|
||||
if (!fab) {
|
||||
return;
|
||||
}
|
||||
|
||||
fab.toggle();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { el, disabled, color, href, activated, show, translucent, size } = this;
|
||||
const inList = hostContext('ion-fab-list', el);
|
||||
@ -144,6 +159,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
||||
|
||||
return (
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
:host(.fab-horizontal-center) {
|
||||
@include position(null, null, null, 50%);
|
||||
@include margin-horizontal(-$fab-size / 2, null);
|
||||
@include margin-horizontal(-$fab-size * 0.5, null);
|
||||
}
|
||||
|
||||
:host(.fab-horizontal-start) {
|
||||
@ -39,7 +39,7 @@
|
||||
}
|
||||
|
||||
:host(.fab-vertical-top.fab-edge) {
|
||||
top: -$fab-size / 2;
|
||||
top: -$fab-size * 0.5;
|
||||
}
|
||||
|
||||
|
||||
@ -48,12 +48,12 @@
|
||||
}
|
||||
|
||||
:host(.fab-vertical-bottom.fab-edge) {
|
||||
bottom: -$fab-size / 2;
|
||||
bottom: -$fab-size * 0.5;
|
||||
}
|
||||
|
||||
|
||||
:host(.fab-vertical-center) {
|
||||
@include margin(-$fab-size / 2, null, null, null);
|
||||
@include margin(-$fab-size * 0.5, null, null, null);
|
||||
|
||||
top: 50%;
|
||||
}
|
||||
|
@ -62,22 +62,23 @@ export class Fab implements ComponentInterface {
|
||||
return this.el.querySelector('ion-fab-button');
|
||||
}
|
||||
|
||||
private onClick = () => {
|
||||
/**
|
||||
* Opens/Closes the FAB list container.
|
||||
* @internal
|
||||
*/
|
||||
@Method()
|
||||
async toggle() {
|
||||
const hasList = !!this.el.querySelector('ion-fab-list');
|
||||
const getButton = this.getFab();
|
||||
const isButtonDisabled = getButton?.disabled;
|
||||
|
||||
if (hasList && !isButtonDisabled) {
|
||||
if (hasList) {
|
||||
this.activated = !this.activated;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { horizontal, vertical, edge } = this;
|
||||
const mode = getIonMode(this);
|
||||
return (
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[`fab-horizontal-${horizontal}`]: horizontal !== undefined,
|
||||
|
@ -11,7 +11,7 @@ $input-ios-font-size: inherit !default;
|
||||
$input-ios-padding-top: $item-ios-padding-top !default;
|
||||
|
||||
/// @prop - Margin end of the input
|
||||
$input-ios-padding-end: ($item-ios-padding-end / 2) !default;
|
||||
$input-ios-padding-end: ($item-ios-padding-end * 0.5) !default;
|
||||
|
||||
/// @prop - Margin bottom of the input
|
||||
$input-ios-padding-bottom: $item-ios-padding-bottom !default;
|
||||
@ -23,25 +23,25 @@ $input-ios-padding-start: 0 !default;
|
||||
$input-ios-by-label-margin-start: $item-ios-padding-start !default;
|
||||
|
||||
/// @prop - Padding top of the inset input
|
||||
$input-ios-inset-padding-top: ($item-ios-padding-top / 2) !default;
|
||||
$input-ios-inset-padding-top: ($item-ios-padding-top * 0.5) !default;
|
||||
|
||||
/// @prop - Padding end of the inset input
|
||||
$input-ios-inset-padding-end: ($item-ios-padding-end / 2) !default;
|
||||
$input-ios-inset-padding-end: ($item-ios-padding-end * 0.5) !default;
|
||||
|
||||
/// @prop - Padding bottom of the inset input
|
||||
$input-ios-inset-padding-bottom: ($item-ios-padding-bottom / 2) !default;
|
||||
$input-ios-inset-padding-bottom: ($item-ios-padding-bottom * 0.5) !default;
|
||||
|
||||
/// @prop - Padding start of the inset input
|
||||
$input-ios-inset-padding-start: ($item-ios-padding-start / 2) !default;
|
||||
$input-ios-inset-padding-start: ($item-ios-padding-start * 0.5) !default;
|
||||
|
||||
/// @prop - Margin top of the inset input
|
||||
$input-ios-inset-margin-top: ($item-ios-padding-top / 2) !default;
|
||||
$input-ios-inset-margin-top: ($item-ios-padding-top * 0.5) !default;
|
||||
|
||||
/// @prop - Margin end of the inset input
|
||||
$input-ios-inset-margin-end: $item-ios-padding-end !default;
|
||||
|
||||
/// @prop - Margin bottom of the inset input
|
||||
$input-ios-inset-margin-bottom: ($item-ios-padding-bottom / 2) !default;
|
||||
$input-ios-inset-margin-bottom: ($item-ios-padding-bottom * 0.5) !default;
|
||||
|
||||
/// @prop - Margin start of the inset input
|
||||
$input-ios-inset-margin-start: 0 !default;
|
||||
|
@ -17,7 +17,7 @@ $input-md-padding-end: 0 !default;
|
||||
$input-md-padding-bottom: 10px !default;
|
||||
|
||||
/// @prop - Margin start of the input
|
||||
$input-md-padding-start: ($item-md-padding-start / 2) !default;
|
||||
$input-md-padding-start: ($item-md-padding-start * 0.5) !default;
|
||||
|
||||
/// @prop - Width of the icon used to clear the input
|
||||
$input-md-input-clear-icon-width: 30px !default;
|
||||
@ -53,25 +53,25 @@ $input-md-highlight-color-valid: ion-color(success, base) !default;
|
||||
$input-md-highlight-color-invalid: ion-color(danger, base) !default;
|
||||
|
||||
/// @prop - Padding top of the inset input
|
||||
$input-md-inset-padding-top: ($item-md-padding-top / 2) !default;
|
||||
$input-md-inset-padding-top: ($item-md-padding-top * 0.5) !default;
|
||||
|
||||
/// @prop - Padding end of the inset input
|
||||
$input-md-inset-padding-end: 0 !default;
|
||||
|
||||
/// @prop - Padding bottom of the inset input
|
||||
$input-md-inset-padding-bottom: ($item-md-padding-bottom / 2) !default;
|
||||
$input-md-inset-padding-bottom: ($item-md-padding-bottom * 0.5) !default;
|
||||
|
||||
/// @prop - Padding start of the inset input
|
||||
$input-md-inset-padding-start: ($item-md-padding-start / 2) !default;
|
||||
$input-md-inset-padding-start: ($item-md-padding-start * 0.5) !default;
|
||||
|
||||
/// @prop - Margin top of the inset input
|
||||
$input-md-inset-margin-top: ($item-md-padding-top / 2) !default;
|
||||
$input-md-inset-margin-top: ($item-md-padding-top * 0.5) !default;
|
||||
|
||||
/// @prop - Margin end of the inset input
|
||||
$input-md-inset-margin-end: $item-md-padding-end !default;
|
||||
|
||||
/// @prop - Margin bottom of the inset input
|
||||
$input-md-inset-margin-bottom: ($item-md-padding-bottom / 2) !default;
|
||||
$input-md-inset-margin-bottom: ($item-md-padding-bottom * 0.5) !default;
|
||||
|
||||
/// @prop - Margin start of the inset input
|
||||
$input-md-inset-margin-start: $item-md-padding-start !default;
|
||||
|
@ -8,7 +8,7 @@
|
||||
--background: #{$item-divider-ios-background};
|
||||
--color: #{$item-divider-ios-color};
|
||||
--padding-start: #{$item-divider-ios-padding-start};
|
||||
--inner-padding-end: #{$item-divider-ios-padding-end / 2};
|
||||
--inner-padding-end: #{$item-divider-ios-padding-end * 0.5};
|
||||
|
||||
@include border-radius(0);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
--min-height: #{$item-ios-min-height};
|
||||
--transition: background-color 200ms linear, opacity 200ms linear;
|
||||
--padding-start: #{$item-ios-padding-start};
|
||||
--inner-padding-end: #{$item-ios-padding-end / 2};
|
||||
--inner-padding-end: #{$item-ios-padding-end * 0.5};
|
||||
--inner-border-width: #{0px 0px $item-ios-border-bottom-width 0px};
|
||||
--background: #{$item-ios-background};
|
||||
--background-activated: #000;
|
||||
@ -170,7 +170,7 @@
|
||||
|
||||
::slotted(ion-avatar[slot="end"]),
|
||||
::slotted(ion-thumbnail[slot="end"]) {
|
||||
@include margin(($item-ios-padding-end / 2));
|
||||
@include margin(($item-ios-padding-end * 0.5));
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ $item-ios-slot-start-margin-start: 0 !default;
|
||||
$item-ios-slot-end-margin-top: null !default;
|
||||
|
||||
/// @prop - Margin end for the end slot
|
||||
$item-ios-slot-end-margin-end: ($item-ios-padding-start / 2) !default;
|
||||
$item-ios-slot-end-margin-end: ($item-ios-padding-start * 0.5) !default;
|
||||
|
||||
/// @prop - Margin bottom for the end slot
|
||||
$item-ios-slot-end-margin-bottom: $item-ios-slot-end-margin-top !default;
|
||||
|
@ -14,7 +14,7 @@ $label-ios-text-color-focused: null !default;
|
||||
$label-ios-margin-top: $item-ios-padding-top !default;
|
||||
|
||||
/// @prop - Margin end of the label
|
||||
$label-ios-margin-end: ($item-ios-padding-end / 2) !default;
|
||||
$label-ios-margin-end: ($item-ios-padding-end * 0.5) !default;
|
||||
|
||||
/// @prop - Margin bottom of the label
|
||||
$label-ios-margin-bottom: $item-ios-padding-bottom !default;
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
import type { GestureDetail } from '../../../utils/gesture';
|
||||
import { createGesture } from '../../../utils/gesture';
|
||||
import { clamp, getElementRoot } from '../../../utils/helpers';
|
||||
import { setCardStatusBarDark, setCardStatusBarDefault } from '../utils';
|
||||
|
||||
import { calculateSpringStep, handleCanDismiss } from './utils';
|
||||
|
||||
@ -18,6 +19,12 @@ export const SwipeToCloseDefaults = {
|
||||
};
|
||||
|
||||
export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: Animation, onDismiss: () => void) => {
|
||||
/**
|
||||
* The step value at which a card modal
|
||||
* is eligible for dismissing via gesture.
|
||||
*/
|
||||
const DISMISS_THRESHOLD = 0.5;
|
||||
|
||||
const height = el.offsetHeight;
|
||||
let isOpen = false;
|
||||
let canDismissBlocksGesture = false;
|
||||
@ -25,6 +32,7 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An
|
||||
let scrollEl: HTMLElement | null = null;
|
||||
const canDismissMaxStep = 0.2;
|
||||
let initialScrollY = true;
|
||||
let lastStep = 0;
|
||||
const getScrollY = () => {
|
||||
if (contentEl && isIonContent(contentEl)) {
|
||||
return (contentEl as HTMLIonContentElement).scrollY;
|
||||
@ -187,6 +195,28 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An
|
||||
const clampedStep = clamp(0.0001, processedStep, maxStep);
|
||||
|
||||
animation.progressStep(clampedStep);
|
||||
|
||||
/**
|
||||
* When swiping down half way, the status bar style
|
||||
* should be reset to its default value.
|
||||
*
|
||||
* We track lastStep so that we do not fire these
|
||||
* functions on every onMove, only when the user has
|
||||
* crossed a certain threshold.
|
||||
*/
|
||||
if (clampedStep >= DISMISS_THRESHOLD && lastStep < DISMISS_THRESHOLD) {
|
||||
setCardStatusBarDefault();
|
||||
|
||||
/**
|
||||
* However, if we swipe back up, then the
|
||||
* status bar style should be set to have light
|
||||
* text on a dark background.
|
||||
*/
|
||||
} else if (clampedStep < DISMISS_THRESHOLD && lastStep >= DISMISS_THRESHOLD) {
|
||||
setCardStatusBarDark();
|
||||
}
|
||||
|
||||
lastStep = clampedStep;
|
||||
};
|
||||
|
||||
const onEnd = (detail: GestureDetail) => {
|
||||
@ -208,7 +238,7 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An
|
||||
* animation can never complete until
|
||||
* canDismiss is checked.
|
||||
*/
|
||||
const shouldComplete = !isAttempingDismissWithCanDismiss && threshold >= 0.5;
|
||||
const shouldComplete = !isAttempingDismissWithCanDismiss && threshold >= DISMISS_THRESHOLD;
|
||||
let newStepValue = shouldComplete ? -0.001 : 0.001;
|
||||
|
||||
if (!shouldComplete) {
|
||||
|
@ -31,6 +31,7 @@ import { mdLeaveAnimation } from './animations/md.leave';
|
||||
import type { MoveSheetToBreakpointOptions } from './gestures/sheet';
|
||||
import { createSheetGesture } from './gestures/sheet';
|
||||
import { createSwipeToCloseGesture } from './gestures/swipe-to-close';
|
||||
import { setCardStatusBarDark, setCardStatusBarDefault } from './utils';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
@ -165,6 +166,10 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
|
||||
/**
|
||||
* If `true`, a backdrop will be displayed behind the modal.
|
||||
* This property controls whether or not the backdrop
|
||||
* darkens the screen when the modal is presented.
|
||||
* It does not control whether or not the backdrop
|
||||
* is active or present in the DOM.
|
||||
*/
|
||||
@Prop() showBackdrop = true;
|
||||
|
||||
@ -466,11 +471,6 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
backdropBreakpoint: this.backdropBreakpoint,
|
||||
});
|
||||
|
||||
await this.currentTransition;
|
||||
|
||||
if (this.isSheetModal) {
|
||||
this.initSheetGesture();
|
||||
|
||||
/**
|
||||
* TODO (FW-937) - In the next major release of Ionic, all card modals
|
||||
* will be swipeable by default. canDismiss will be used to determine if the
|
||||
@ -480,7 +480,22 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
* If we did not do this check, then not using swipeToClose would mean you could
|
||||
* not run canDismiss on swipe as there would be no swipe gesture created.
|
||||
*/
|
||||
} else if (this.swipeToClose || (this.canDismiss !== undefined && this.presentingElement !== undefined)) {
|
||||
const hasCardModal = this.swipeToClose || (this.canDismiss !== undefined && this.presentingElement !== undefined);
|
||||
|
||||
/**
|
||||
* We need to change the status bar at the
|
||||
* start of the animation so that it completes
|
||||
* by the time the card animation is done.
|
||||
*/
|
||||
if (hasCardModal && getIonMode(this) === 'ios') {
|
||||
setCardStatusBarDark();
|
||||
}
|
||||
|
||||
await this.currentTransition;
|
||||
|
||||
if (this.isSheetModal) {
|
||||
this.initSheetGesture();
|
||||
} else if (hasCardModal) {
|
||||
await this.initSwipeToClose();
|
||||
}
|
||||
|
||||
@ -631,6 +646,17 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to start the status bar change
|
||||
* before the animation so that the change
|
||||
* finishes when the dismiss animation does.
|
||||
* TODO (FW-937)
|
||||
*/
|
||||
const hasCardModal = this.swipeToClose || (this.canDismiss !== undefined && this.presentingElement !== undefined);
|
||||
if (hasCardModal && getIonMode(this) === 'ios') {
|
||||
setCardStatusBarDefault();
|
||||
}
|
||||
|
||||
/* tslint:disable-next-line */
|
||||
if (typeof window !== 'undefined' && this.keyboardOpenCallback) {
|
||||
window.removeEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
|
||||
|
11
core/src/components/modal/utils.spec.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { getBackdropValueForSheet } from './utils';
|
||||
|
||||
describe('getBackdropValueForSheet()', () => {
|
||||
it('should return a valid integer when backdropBreakpoint is 1', () => {
|
||||
/**
|
||||
* Issue: https://github.com/ionic-team/ionic-framework/issues/25402
|
||||
*/
|
||||
const backdropBreakpoint = 1;
|
||||
expect(getBackdropValueForSheet(1, backdropBreakpoint)).toBe(0);
|
||||
});
|
||||
});
|
@ -1,3 +1,6 @@
|
||||
import { StatusBar, Style } from '../../utils/native/status-bar';
|
||||
import { win } from '../../utils/window';
|
||||
|
||||
/**
|
||||
* Use y = mx + b to
|
||||
* figure out the backdrop value
|
||||
@ -23,7 +26,15 @@ export const getBackdropValueForSheet = (x: number, backdropBreakpoint: number)
|
||||
*
|
||||
* This is simplified from:
|
||||
* m = (1 - 0) / (maxBreakpoint - backdropBreakpoint)
|
||||
*
|
||||
* If the backdropBreakpoint is 1, we return 0 as the
|
||||
* backdrop is completely hidden.
|
||||
*
|
||||
*/
|
||||
if (backdropBreakpoint === 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const slope = 1 / (1 - backdropBreakpoint);
|
||||
|
||||
/**
|
||||
@ -49,3 +60,31 @@ export const getBackdropValueForSheet = (x: number, backdropBreakpoint: number)
|
||||
|
||||
return x * slope + b;
|
||||
};
|
||||
|
||||
/**
|
||||
* The tablet/desktop card modal activates
|
||||
* when the window width is >= 768.
|
||||
* At that point, the presenting element
|
||||
* is not transformed, so we do not need to
|
||||
* adjust the status bar color.
|
||||
*
|
||||
* Note: We check supportsDefaultStatusBarStyle so that
|
||||
* Capacitor <= 2 users do not get their status bar
|
||||
* stuck in an inconsistent state due to a lack of
|
||||
* support for Style.Default.
|
||||
*/
|
||||
export const setCardStatusBarDark = () => {
|
||||
if (!win || win.innerWidth >= 768 || !StatusBar.supportsDefaultStatusBarStyle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StatusBar.setStyle({ style: Style.Dark });
|
||||
};
|
||||
|
||||
export const setCardStatusBarDefault = () => {
|
||||
if (!win || win.innerWidth >= 768 || !StatusBar.supportsDefaultStatusBarStyle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StatusBar.setStyle({ style: Style.Default });
|
||||
};
|
||||
|
@ -67,7 +67,7 @@ export class Nav implements NavOutlet {
|
||||
|
||||
/**
|
||||
* By default `ion-nav` animates transition between pages based in the mode (ios or material design).
|
||||
* However, this property allows to create custom transition using `AnimateBuilder` functions.
|
||||
* However, this property allows to create custom transition using `AnimationBuilder` functions.
|
||||
*/
|
||||
@Prop() animation?: AnimationBuilder;
|
||||
|
||||
|
@ -24,7 +24,8 @@ import type { PickerColumnItem } from './picker-column-internal-interfaces';
|
||||
})
|
||||
export class PickerColumnInternal implements ComponentInterface {
|
||||
private destroyScrollListener?: () => void;
|
||||
private hapticsStarted = false;
|
||||
private isScrolling = false;
|
||||
private scrollEndCallback?: () => void;
|
||||
private isColumnVisible = false;
|
||||
|
||||
@State() isActive = false;
|
||||
@ -187,11 +188,30 @@ export class PickerColumnInternal implements ComponentInterface {
|
||||
const isColumnActive = inputModeColumn === undefined || inputModeColumn === this.el;
|
||||
|
||||
if (!useInputMode || !isColumnActive) {
|
||||
this.isActive = false;
|
||||
this.setInputModeActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.isActive = true;
|
||||
this.setInputModeActive(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Setting isActive will cause a re-render.
|
||||
* As a result, we do not want to cause the
|
||||
* re-render mid scroll as this will cause
|
||||
* the picker column to jump back to
|
||||
* whatever value was selected at the
|
||||
* start of the scroll interaction.
|
||||
*/
|
||||
private setInputModeActive = (state: boolean) => {
|
||||
if (this.isScrolling) {
|
||||
this.scrollEndCallback = () => {
|
||||
this.isActive = state;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
this.isActive = state;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -213,9 +233,9 @@ export class PickerColumnInternal implements ComponentInterface {
|
||||
timeout = undefined;
|
||||
}
|
||||
|
||||
if (!this.hapticsStarted) {
|
||||
if (!this.isScrolling) {
|
||||
hapticSelectionStart();
|
||||
this.hapticsStarted = true;
|
||||
this.isScrolling = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,6 +263,21 @@ export class PickerColumnInternal implements ComponentInterface {
|
||||
activeElement.classList.add(PICKER_COL_ACTIVE);
|
||||
|
||||
timeout = setTimeout(() => {
|
||||
this.isScrolling = false;
|
||||
hapticSelectionEnd();
|
||||
|
||||
/**
|
||||
* Certain tasks (such as those that
|
||||
* cause re-renders) should only be done
|
||||
* once scrolling has finished, otherwise
|
||||
* flickering may occur.
|
||||
*/
|
||||
const { scrollEndCallback } = this;
|
||||
if (scrollEndCallback) {
|
||||
scrollEndCallback();
|
||||
this.scrollEndCallback = undefined;
|
||||
}
|
||||
|
||||
const dataIndex = activeElement.getAttribute('data-index');
|
||||
|
||||
/**
|
||||
@ -259,8 +294,6 @@ export class PickerColumnInternal implements ComponentInterface {
|
||||
|
||||
if (selectedItem.value !== this.value) {
|
||||
this.setValue(selectedItem.value);
|
||||
hapticSelectionEnd();
|
||||
this.hapticsStarted = false;
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
|
@ -88,4 +88,4 @@ $picker-ios-option-font-size: 20px !default;
|
||||
$picker-ios-option-height: 42px !default;
|
||||
|
||||
/// @prop - Offset y of the picker option
|
||||
$picker-ios-option-offset-y: (($picker-ios-height - $picker-ios-toolbar-height) / 2) - ($picker-ios-option-height / 2) - 10 !default;
|
||||
$picker-ios-option-offset-y: (($picker-ios-height - $picker-ios-toolbar-height) * 0.5) - ($picker-ios-option-height * 0.5) - 10 !default;
|
||||
|
@ -73,7 +73,7 @@ $picker-md-option-font-size: 22px !default;
|
||||
$picker-md-option-height: 42px !default;
|
||||
|
||||
/// @prop - Offset y of the picker option
|
||||
$picker-md-option-offset-y: (($picker-md-height - $picker-md-toolbar-height) / 2) - ($picker-md-option-height / 2) - 10 !default;
|
||||
$picker-md-option-offset-y: (($picker-md-height - $picker-md-toolbar-height) * 0.5) - ($picker-md-option-height * 0.5) - 10 !default;
|
||||
|
||||
/// @prop - Text color of the selected picker option
|
||||
$picker-md-option-selected-color: ion-color(primary, base) !default;
|
||||
|
@ -128,6 +128,10 @@ export class Popover implements ComponentInterface, PopoverInterface {
|
||||
|
||||
/**
|
||||
* If `true`, a backdrop will be displayed behind the popover.
|
||||
* This property controls whether or not the backdrop
|
||||
* darkens the screen when the popover is presented.
|
||||
* It does not control whether or not the backdrop
|
||||
* is active or present in the DOM.
|
||||
*/
|
||||
@Prop() showBackdrop = true;
|
||||
|
||||
|
59
core/src/components/popover/test/adjustment/index.html
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Popover - Adjustment</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<script type="module">
|
||||
import { popoverController } from '../../../../dist/ionic/index.esm.js';
|
||||
window.popoverController = popoverController;
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-content>
|
||||
<p style="text-align: center">Click everywhere to open the popover.</p>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
document.querySelector('ion-content').addEventListener('click', handleButtonClick);
|
||||
|
||||
async function handleButtonClick(ev) {
|
||||
const popover = await popoverController.create({
|
||||
component: 'popover-example-page',
|
||||
event: ev,
|
||||
reference: 'event',
|
||||
});
|
||||
|
||||
popover.present();
|
||||
}
|
||||
|
||||
customElements.define(
|
||||
'popover-example-page',
|
||||
class PopoverContent extends HTMLElement {
|
||||
connectedCallback() {
|
||||
this.innerHTML = `
|
||||
<ion-list>
|
||||
<ion-list-header>Ionic</ion-list-header>
|
||||
<ion-item button>Learn Ionic</ion-item>
|
||||
<ion-item button>Documentation</ion-item>
|
||||
<ion-item button>Showcase</ion-item>
|
||||
<ion-item button>GitHub Repo</ion-item>
|
||||
<ion-item button>Another Item</ion-item>
|
||||
</ion-list>
|
||||
`;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
32
core/src/components/popover/test/adjustment/popover.e2e.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('popover: adjustment', async () => {
|
||||
test('should not render the popover offscreen', async ({ page }) => {
|
||||
await page.goto('/src/components/popover/test/adjustment');
|
||||
|
||||
/**
|
||||
* We need to click in an area where
|
||||
* there is not enough room to show the popover
|
||||
* below the click coordinates but not enough
|
||||
* room above the click coordinates that we
|
||||
* can just move the popover to without it going
|
||||
* offscreen.
|
||||
*/
|
||||
await page.setViewportSize({
|
||||
width: 500,
|
||||
height: 400,
|
||||
});
|
||||
|
||||
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
||||
|
||||
await page.mouse.click(300, 300);
|
||||
|
||||
await ionPopoverDidPresent.next();
|
||||
|
||||
const popoverContent = page.locator('ion-popover .popover-content');
|
||||
const box = (await popoverContent.boundingBox())!;
|
||||
|
||||
expect(box.y > 0).toBe(true);
|
||||
});
|
||||
});
|