chore(): sync with main:

This commit is contained in:
Liam DeBeasi
2022-10-11 11:38:27 -04:00
464 changed files with 2022 additions and 2820 deletions

View File

@@ -32,9 +32,14 @@ jobs:
with:
node-version: 16
- name: Configure Identity
# Commits from github-actions do not
# trigger other GitHub Actions. As a result,
# we publish releases from Ionitron instead
# so actions run when merging the release branch
# back into main.
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git config user.name ionitron
git config user.email hi@ionicframework.com
shell: bash
- name: Install Dependencies
run: npm ci --no-package-lock && lerna bootstrap --ignore-scripts -- --legacy-peer-deps

View File

@@ -3,6 +3,27 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.3.0](https://github.com/ionic-team/ionic-framework/compare/v6.2.9...v6.3.0) (2022-10-05)
### Bug Fixes
* **list:** remove extra border in md inset list items ([#25972](https://github.com/ionic-team/ionic-framework/issues/25972)) ([3eb3dd5](https://github.com/ionic-team/ionic-framework/commit/3eb3dd5afa02f7257e2594f56efe570be83719b6)), closes [#25278](https://github.com/ionic-team/ionic-framework/issues/25278)
* **range:** indication when range knob is focused ([#25827](https://github.com/ionic-team/ionic-framework/issues/25827)) ([2c815cf](https://github.com/ionic-team/ionic-framework/commit/2c815cff139a0061883d3eef47816aea8801dcf4))
### Features
* **alert:** accept Promise for button handler ([#25702](https://github.com/ionic-team/ionic-framework/issues/25702)) ([8e4783c](https://github.com/ionic-team/ionic-framework/commit/8e4783c17298e8f7654590108430e80f22ed6a7a)), closes [#25700](https://github.com/ionic-team/ionic-framework/issues/25700)
* **angular:** use standalone components with routing ([#25589](https://github.com/ionic-team/ionic-framework/issues/25589)) ([3c84d48](https://github.com/ionic-team/ionic-framework/commit/3c84d48cfa87810896364cb7ca16efcbdd7e8b07)), closes [#25404](https://github.com/ionic-team/ionic-framework/issues/25404)
* **button:** submit from outside of form ([#25913](https://github.com/ionic-team/ionic-framework/issues/25913)) ([b139838](https://github.com/ionic-team/ionic-framework/commit/b13983848c9ea7387062953412eaae744c001ec7)), closes [#21194](https://github.com/ionic-team/ionic-framework/issues/21194)
* **datetime-button:** support multiple date selection ([#25971](https://github.com/ionic-team/ionic-framework/issues/25971)) ([a56a4a9](https://github.com/ionic-team/ionic-framework/commit/a56a4a9c0528fe77859963f5b801a3d645be0b23))
* **datetime:** add header text to multiple selection; improve header consistency between modes ([#25817](https://github.com/ionic-team/ionic-framework/issues/25817)) ([8a1b3c5](https://github.com/ionic-team/ionic-framework/commit/8a1b3c5f300a1ec953d406b65601f84fa49aa807))
## [6.2.9](https://github.com/ionic-team/ionic-framework/compare/v6.2.8...v6.2.9) (2022-09-28)

View File

@@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.3.0 Manganese](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)
### Features
* **angular:** use standalone components with routing ([#25589](https://github.com/ionic-team/ionic/issues/25589)) ([3c84d48](https://github.com/ionic-team/ionic/commit/3c84d48cfa87810896364cb7ca16efcbdd7e8b07)), closes [#25404](https://github.com/ionic-team/ionic/issues/25404)
* **button:** submit from outside of form ([#25913](https://github.com/ionic-team/ionic/issues/25913)) ([b139838](https://github.com/ionic-team/ionic/commit/b13983848c9ea7387062953412eaae744c001ec7)), closes [#21194](https://github.com/ionic-team/ionic/issues/21194)
* **datetime:** add header text to multiple selection; improve header consistency between modes ([#25817](https://github.com/ionic-team/ionic/issues/25817)) ([8a1b3c5](https://github.com/ionic-team/ionic/commit/8a1b3c5f300a1ec953d406b65601f84fa49aa807))
## [6.2.9](https://github.com/ionic-team/ionic/compare/v6.2.8...v6.2.9) (2022-09-28)
**Note:** Version bump only for package @ionic/angular

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/angular",
"version": "6.2.9",
"version": "6.3.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular",
"version": "6.2.9",
"version": "6.3.0",
"license": "MIT",
"dependencies": {
"@ionic/core": "^6.2.9",
"@ionic/core": "^6.3.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.0.0"
},
@@ -1023,9 +1023,9 @@
"dev": true
},
"node_modules/@ionic/core": {
"version": "6.2.9",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.9.tgz",
"integrity": "sha512-d2KBXYUKBND2AD8aMgash3O/t04IDc/DHHMshcOydfNJ5qqAxwJYzZR7hs96UknCcIlhHk1pb5C29epkv7gOcQ==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==",
"dependencies": {
"@stencil/core": "^2.18.0",
"ionicons": "^6.0.3",
@@ -7951,9 +7951,9 @@
"dev": true
},
"@ionic/core": {
"version": "6.2.9",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.9.tgz",
"integrity": "sha512-d2KBXYUKBND2AD8aMgash3O/t04IDc/DHHMshcOydfNJ5qqAxwJYzZR7hs96UknCcIlhHk1pb5C29epkv7gOcQ==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==",
"requires": {
"@stencil/core": "^2.18.0",
"ionicons": "^6.0.3",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "6.2.9",
"version": "6.3.0",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -46,7 +46,7 @@
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"dependencies": {
"@ionic/core": "^6.2.9",
"@ionic/core": "^6.3.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.0.0"
},

View File

@@ -30,5 +30,5 @@ export abstract class EnvironmentInjector implements Injector {
/**
* @internal
*/
abstract onDestroy(callback: () => void): void;
abstract onDestroy?(callback: () => void): void;
}

View File

@@ -14,6 +14,7 @@ import {
Optional,
Output,
SkipSelf,
Input,
} from '@angular/core';
import { OutletContext, Router, ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET } from '@angular/router';
import { componentOnReady } from '@ionic/core';
@@ -55,6 +56,16 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
tabsPrefix: string | undefined;
/**
* @experimental
*
* The `EnvironmentInjector` provider instance from the parent component.
* Required for using standalone components with `ion-router-outlet`.
*
* Will be deprecated and removed when Angular 13 support is dropped.
*/
@Input() environmentInjector: EnvironmentInjector;
@Output() stackEvents = new EventEmitter<any>();
// eslint-disable-next-line @angular-eslint/no-output-rename
@Output('activate') activateEvents = new EventEmitter<any>();
@@ -88,7 +99,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
@Optional() @Attribute('tabs') tabs: string,
private config: Config,
private navCtrl: NavController,
@Optional() private environmentInjector: EnvironmentInjector,
@Optional() private componentFactoryResolver: ComponentFactoryResolver,
commonLocation: Location,
elementRef: ElementRef,
@@ -234,20 +244,24 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
} else {
const snapshot = (activatedRoute as any)._futureSnapshot;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const component = snapshot.routeConfig!.component as any;
/**
* Angular 14 introduces a new `loadComponent` property to the route config,
* that assigns the component to load to the `component` property of
* the route snapshot. We can check for the presence of this property
* to determine if the route is using standalone components.
*
* TODO: FW-1631: Remove this check when supporting standalone components
* Angular 14 introduces a new `loadComponent` property to the route config.
* This function will assign a `component` property to the route snapshot.
* We check for the presence of this property to determine if the route is
* using standalone components.
*/
if (component == null && snapshot.component) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (snapshot.routeConfig!.component == null && this.environmentInjector == null) {
console.warn(
'[Ionic Warning]: Standalone components are not currently supported with ion-router-outlet. You can track this feature request at https://github.com/ionic-team/ionic-framework/issues/25404'
'[Ionic Warning]: You must supply an environmentInjector to use standalone components with routing:\n\n' +
'In your component class, add:\n\n' +
` import { EnvironmentInjector } from '@angular/core';\n` +
' constructor(public environmentInjector: EnvironmentInjector) {}\n' +
'\n' +
'In your router outlet template, add:\n\n' +
' <ion-router-outlet [environmentInjector]="environmentInjector"></ion-router-outlet>\n\n' +
'Alternatively, if you are routing within ion-tabs:\n\n' +
' <ion-tabs [environmentInjector]="environmentInjector"></ion-tabs>'
);
return;
}
@@ -267,6 +281,9 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
*/
resolverOrInjector = resolverOrInjector || this.componentFactoryResolver;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const component = snapshot.routeConfig!.component ?? snapshot.component;
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
// Backwards compatibility for Angular 13 and lower
const factory = resolverOrInjector.resolveComponentFactory(component);

View File

@@ -1,5 +1,6 @@
import { Component, ContentChild, EventEmitter, HostListener, Output, ViewChild } from '@angular/core';
import { Component, ContentChild, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
import { EnvironmentInjector } from '../../di/r3_injector';
import { NavController } from '../../providers/nav-controller';
import { IonTabBar } from '../proxies';
@@ -10,7 +11,12 @@ import { StackEvent } from './stack-utils';
selector: 'ion-tabs',
template: ` <ng-content select="[slot=top]"></ng-content>
<div class="tabs-inner">
<ion-router-outlet #outlet tabs="true" (stackEvents)="onPageSelected($event)"></ion-router-outlet>
<ion-router-outlet
#outlet
tabs="true"
[environmentInjector]="environmentInjector"
(stackEvents)="onPageSelected($event)"
></ion-router-outlet>
</div>
<ng-content></ng-content>`,
styles: [
@@ -46,6 +52,16 @@ export class IonTabs {
@ViewChild('outlet', { read: IonRouterOutlet, static: false }) outlet: IonRouterOutlet;
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
/**
* @experimental
*
* The `EnvironmentInjector` provider instance from the parent component.
* Required for using standalone components with `ion-router-outlet`.
*
* Will be deprecated and removed when Angular 13 support is dropped.
*/
@Input() environmentInjector: EnvironmentInjector;
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();

View File

@@ -242,13 +242,13 @@ export declare interface IonButton extends Components.IonButton {
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type']
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type']
})
@Component({
selector: 'ion-button',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type']
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type']
})
export class IonButton {
protected el: HTMLElement;
@@ -530,14 +530,14 @@ export declare interface IonDatetime extends Components.IonDatetime {
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'value', 'yearValues'],
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', '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']
})
@Component({
selector: 'ion-datetime',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'value', 'yearValues']
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', '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 {
protected el: HTMLElement;

View File

@@ -0,0 +1,9 @@
describe('Routing with Standalone Components', () => {
beforeEach(() => {
cy.visit('/version-test/standalone');
});
it('should render the component', () => {
cy.get('ion-content').contains('This is a standalone component rendered from a route.');
});
});

View File

@@ -0,0 +1,3 @@
<ion-app>
<ion-router-outlet [environmentInjector]="environmentInjector"></ion-router-outlet>
</ion-app>

View File

@@ -0,0 +1,11 @@
import { Component, EnvironmentInjector } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(public environmentInjector: EnvironmentInjector) { }
}

View File

@@ -0,0 +1,4 @@
<ion-content>
<p>This is a standalone component rendered from a route.</p>
<ion-button routerLink="/">Return home</ion-button>
</ion-content>

View File

@@ -0,0 +1,12 @@
import { Component } from "@angular/core";
import { RouterModule } from "@angular/router";
import { IonicModule } from '@ionic/angular';
@Component({
selector: 'app-standalone',
templateUrl: './standalone.component.html',
standalone: true,
imports: [IonicModule, RouterModule]
})
export class StandaloneComponent { }

View File

@@ -0,0 +1,15 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'standalone',
loadComponent: () => import('./standalone/standalone.component').then(m => m.StandaloneComponent)
}
])
],
exports: [RouterModule]
})
export class VersionTestRoutingModule { }

View File

@@ -1,7 +0,0 @@
# Ionic Angular Test App
```
npm install
npm run sync:build
npm start
```

View File

@@ -1,6 +1,6 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { VersionTestComponent } from ".";
import { VersionTestComponent } from "./version-test.component";
@NgModule({
imports: [

View File

@@ -0,0 +1,21 @@
{
"compileOnSave": false,
"compilerOptions": {
"importHelpers": true,
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"module": "es2020",
"target": "es2020",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"plugins": [
{
"name": "typescript-eslint-language-service"
}
]
}
}

View File

@@ -31,3 +31,5 @@ cp -R $FULL_BASE_DIR $BUILD_APP_DIR
# Then we can copy the specific app which
# will override any files in the base application.
cp -R $FULL_APP_DIR $BUILD_APP_DIR
echo "Copied test app files for ${APP_DIR}"

35
angular/test/sync-e2e.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# The directory where the source
# for each specific application is.
APPS_DIR="apps"
# The directory where the
# base application logic is
BASE_DIR="base"
BUILD_DIR="build"
# The specific application
# we are building
APP_DIR="${1}"
# The full path to the specific application.
FULL_APP_DIR="${APPS_DIR}/${APP_DIR}/e2e"
# The full path to the base application.
FULL_BASE_DIR="${BASE_DIR}/e2e"
# The full path to the built application.
BUILD_APP_DIR="${BUILD_DIR}/${APP_DIR}/"
# Make the build directory if it does not already exist.
mkdir -p $BUILD_DIR
# First we need to copy the base application
cp -R $FULL_BASE_DIR $BUILD_APP_DIR
# Then we can copy the specific app which
# will override any files in the base application.
cp -R $FULL_APP_DIR $BUILD_APP_DIR
echo "Synced e2e tests for ${APP_DIR}"

View File

@@ -1,2 +1,5 @@
src/components/slides/swiper/swiper.bundle.js
src/components.d.ts
**/test/**/*.spec.ts
**/test/**/*.spec.tsx
**/test/**/e2e.ts

View File

@@ -13,7 +13,8 @@ module.exports = {
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
"sourceType": "module",
"project": "tsconfig.json"
},
"plugins": [
"@typescript-eslint",
@@ -31,6 +32,14 @@ module.exports = {
"no-useless-catch": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"no-case-declarations": "off",
"@typescript-eslint/strict-boolean-expressions": [
"error",
{
"allowNullableBoolean": true,
"allowNullableString": true,
"allowAny": true
}
],
"custom-rules/no-component-on-ready-method": "error"
}
};

View File

@@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)
### Bug Fixes
* **list:** remove extra border in md inset list items ([#25972](https://github.com/ionic-team/ionic/issues/25972)) ([3eb3dd5](https://github.com/ionic-team/ionic/commit/3eb3dd5afa02f7257e2594f56efe570be83719b6)), closes [#25278](https://github.com/ionic-team/ionic/issues/25278)
* **range:** indication when range knob is focused ([#25827](https://github.com/ionic-team/ionic/issues/25827)) ([2c815cf](https://github.com/ionic-team/ionic/commit/2c815cff139a0061883d3eef47816aea8801dcf4))
### Features
* **alert:** accept Promise for button handler ([#25702](https://github.com/ionic-team/ionic/issues/25702)) ([8e4783c](https://github.com/ionic-team/ionic/commit/8e4783c17298e8f7654590108430e80f22ed6a7a)), closes [#25700](https://github.com/ionic-team/ionic/issues/25700)
* **button:** submit from outside of form ([#25913](https://github.com/ionic-team/ionic/issues/25913)) ([b139838](https://github.com/ionic-team/ionic/commit/b13983848c9ea7387062953412eaae744c001ec7)), closes [#21194](https://github.com/ionic-team/ionic/issues/21194)
* **datetime-button:** support multiple date selection ([#25971](https://github.com/ionic-team/ionic/issues/25971)) ([a56a4a9](https://github.com/ionic-team/ionic/commit/a56a4a9c0528fe77859963f5b801a3d645be0b23))
* **datetime:** add header text to multiple selection; improve header consistency between modes ([#25817](https://github.com/ionic-team/ionic/issues/25817)) ([8a1b3c5](https://github.com/ionic-team/ionic/commit/8a1b3c5f300a1ec953d406b65601f84fa49aa807))
## [6.2.9](https://github.com/ionic-team/ionic/compare/v6.2.8...v6.2.9) (2022-09-28)

View File

@@ -203,6 +203,7 @@ ion-button,prop,disabled,boolean,false,false,true
ion-button,prop,download,string | undefined,undefined,false,false
ion-button,prop,expand,"block" | "full" | undefined,undefined,false,true
ion-button,prop,fill,"clear" | "default" | "outline" | "solid" | undefined,undefined,false,true
ion-button,prop,form,HTMLFormElement | string | undefined,undefined,false,false
ion-button,prop,href,string | undefined,undefined,false,false
ion-button,prop,mode,"ios" | "md",undefined,false,false
ion-button,prop,rel,string | undefined,undefined,false,false
@@ -397,6 +398,7 @@ ion-datetime,prop,showDefaultButtons,boolean,false,false,false
ion-datetime,prop,showDefaultTimeLabel,boolean,true,false,false
ion-datetime,prop,showDefaultTitle,boolean,false,false,false
ion-datetime,prop,size,"cover" | "fixed",'fixed',false,false
ion-datetime,prop,titleSelectedDatesFormatter,((selectedDates: string[]) => string) | undefined,undefined,false,false
ion-datetime,prop,value,null | string | string[] | undefined,undefined,false,false
ion-datetime,prop,yearValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,method,cancel,cancel(closeOverlay?: boolean) => Promise<void>
@@ -1306,7 +1308,7 @@ ion-textarea,method,setFocus,setFocus() => Promise<void>
ion-textarea,event,ionBlur,FocusEvent,true
ion-textarea,event,ionChange,TextareaChangeEventDetail,true
ion-textarea,event,ionFocus,FocusEvent,true
ion-textarea,event,ionInput,InputEvent | null,true
ion-textarea,event,ionInput,InputEvent,true
ion-textarea,css-prop,--background
ion-textarea,css-prop,--border-radius
ion-textarea,css-prop,--color

View File

@@ -1,12 +1,12 @@
{
"name": "@ionic/core",
"version": "6.2.9",
"version": "6.3.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/core",
"version": "6.2.9",
"version": "6.3.0",
"license": "MIT",
"dependencies": {
"@stencil/core": "^2.18.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "6.2.9",
"version": "6.3.0",
"description": "Base components for Ionic",
"keywords": [
"ionic",

View File

@@ -5,7 +5,7 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { AccordionGroupChangeEventDetail, ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, BreadcrumbCollapsedClickEventDetail, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimePresentation, FrameworkDelegate, InputChangeEventDetail, InputInputEventDetail, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, ModalBreakpointChangeEventDetail, ModalHandleBehavior, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, PopoverSize, PositionAlign, PositionReference, PositionSide, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, TriggerAction, ViewController } from "./interface";
import { AccordionGroupChangeEventDetail, ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, BreadcrumbCollapsedClickEventDetail, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimePresentation, FrameworkDelegate, InputChangeEventDetail, InputInputEventDetail, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, ModalBreakpointChangeEventDetail, ModalHandleBehavior, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, PopoverSize, PositionAlign, PositionReference, PositionSide, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, TitleSelectedDatesFormatter, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, TriggerAction, ViewController } from "./interface";
import { IonicSafeString } from "./utils/sanitization";
import { AlertAttributes } from "./components/alert/alert-interface";
import { CounterFormatter } from "./components/item/item-interface";
@@ -382,6 +382,10 @@ export namespace Components {
* Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"` for a transparent button with a border, or to `"solid"` for a button with a filled background. The default fill is `"solid"` except inside of a toolbar, where the default is `"clear"`.
*/
"fill"?: 'clear' | 'outline' | 'solid' | 'default';
/**
* The HTML form element or form element id. Used to submit a form when the button is not a child of the form.
*/
"form"?: string | HTMLFormElement;
/**
* Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered.
*/
@@ -829,13 +833,17 @@ export namespace Components {
*/
"showDefaultTimeLabel": boolean;
/**
* If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date.
* If `true`, a header will be shown above the calendar picker. This will include both the slotted title, and the selected date.
*/
"showDefaultTitle": boolean;
/**
* If `cover`, the `ion-datetime` will expand to cover the full width of its container. If `fixed`, the `ion-datetime` will have a fixed width.
*/
"size": 'cover' | 'fixed';
/**
* A callback used to format the header text that shows how many dates are selected. Only used if there are 0 or more than 1 selected (i.e. unused for exactly 1). By default, the header text is set to "numberOfDates days".
*/
"titleSelectedDatesFormatter"?: TitleSelectedDatesFormatter;
/**
* The value of the datetime as a valid ISO 8601 datetime string. Should be an array of strings if `multiple="true"`.
*/
@@ -4138,6 +4146,10 @@ declare namespace LocalJSX {
* Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"` for a transparent button with a border, or to `"solid"` for a button with a filled background. The default fill is `"solid"` except inside of a toolbar, where the default is `"clear"`.
*/
"fill"?: 'clear' | 'outline' | 'solid' | 'default';
/**
* The HTML form element or form element id. Used to submit a form when the button is not a child of the form.
*/
"form"?: string | HTMLFormElement;
/**
* Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered.
*/
@@ -4601,13 +4613,17 @@ declare namespace LocalJSX {
*/
"showDefaultTimeLabel"?: boolean;
/**
* If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date.
* If `true`, a header will be shown above the calendar picker. This will include both the slotted title, and the selected date.
*/
"showDefaultTitle"?: boolean;
/**
* If `cover`, the `ion-datetime` will expand to cover the full width of its container. If `fixed`, the `ion-datetime` will have a fixed width.
*/
"size"?: 'cover' | 'fixed';
/**
* A callback used to format the header text that shows how many dates are selected. Only used if there are 0 or more than 1 selected (i.e. unused for exactly 1). By default, the header text is set to "numberOfDates days".
*/
"titleSelectedDatesFormatter"?: TitleSelectedDatesFormatter;
/**
* The value of the datetime as a valid ISO 8601 datetime string. Should be an array of strings if `multiple="true"`.
*/

View File

@@ -216,7 +216,7 @@ export class AccordionGroup implements ComponentInterface {
* to the array.
*/
if (multiple) {
const groupValue = value || [];
const groupValue = value ?? [];
const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];
const valueExists = processedValue.find((v) => v === accordionValue);
if (valueExists === undefined && accordionValue !== undefined) {
@@ -231,7 +231,7 @@ export class AccordionGroup implements ComponentInterface {
* out of the values array or unset the value.
*/
if (multiple) {
const groupValue = value || [];
const groupValue = value ?? [];
const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];
this.setValue(processedValue.filter((v) => v !== accordionValue));
} else {

View File

@@ -157,11 +157,9 @@ export class Accordion implements ComponentInterface {
}
// This is not defined in unit tests
const ionItem =
slot.assignedElements &&
(slot.assignedElements().find((el) => el.tagName === 'ION-ITEM') as HTMLIonItemElement | undefined);
if (slot.assignedElements === undefined) return;
return ionItem;
return slot.assignedElements().find((el) => el.tagName === 'ION-ITEM') as HTMLIonItemElement | undefined;
};
private setAria = (expanded = false) => {

View File

@@ -53,10 +53,12 @@ export type AlertTextareaAttributes = { [key: string]: any };
*/
export type AlertInputAttributes = { [key: string]: any };
type AlertButtonOverlayHandler = boolean | void | { [key: string]: any };
export interface AlertButton {
text: string;
role?: 'cancel' | 'destructive' | string;
cssClass?: string | string[];
id?: string;
handler?: (value: any) => boolean | void | { [key: string]: any };
handler?: (value: any) => AlertButtonOverlayHandler | Promise<AlertButtonOverlayHandler>;
}

View File

@@ -241,7 +241,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
handler: i.handler,
min: i.min,
max: i.max,
cssClass: i.cssClass || '',
cssClass: i.cssClass ?? '',
attributes: i.attributes || {},
tabindex: i.type === 'radio' && i !== focusable ? -1 : 0,
} as AlertInput)
@@ -335,24 +335,24 @@ export class Alert implements ComponentInterface, OverlayInterface {
forceUpdate(this);
}
private buttonClick(button: AlertButton) {
private async buttonClick(button: AlertButton) {
const role = button.role;
const values = this.getValues();
if (isCancel(role)) {
return this.dismiss({ values }, role);
}
const returnData = this.callButtonHandler(button, values);
const returnData = await this.callButtonHandler(button, values);
if (returnData !== false) {
return this.dismiss({ values, ...returnData }, button.role);
}
return Promise.resolve(false);
return false;
}
private callButtonHandler(button: AlertButton | undefined, data?: any) {
private async callButtonHandler(button: AlertButton | undefined, data?: any) {
if (button?.handler) {
// a handler has been provided, execute it
// pass the handler the values from the inputs
const returnData = safeCall(button.handler, data);
const returnData = await safeCall(button.handler, data);
if (returnData === false) {
// if the return value of the handler is false then do not dismiss
return false;
@@ -596,7 +596,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
role={role}
aria-modal="true"
aria-labelledby={ariaLabelledBy}
aria-describedby={message ? msgId : null}
aria-describedby={message !== undefined ? msgId : null}
tabindex="-1"
{...(htmlAttributes as any)}
style={{

View File

@@ -54,6 +54,29 @@ test.describe('alert: basic', () => {
expect(alert).toHaveAttribute('data-testid', 'basic-alert');
});
test('should dismiss when async handler resolves', async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/basic`);
const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent');
const ionAlertDidDismiss = await page.spyOnEvent('ionAlertDidDismiss');
const ionLoadingDidDismiss = await page.spyOnEvent('ionLoadingDidDismiss');
const alert = page.locator('ion-alert');
await page.click('#asyncHandler');
await ionAlertDidPresent.next();
await page.click('.alert-button');
await expect(alert).toBeVisible();
await ionLoadingDidDismiss.next();
await ionAlertDidDismiss.next();
await expect(alert).toBeHidden();
});
test.describe('should not have visual regressions', () => {
test('header, subheader, message', async ({ page }) => {
await testAlert(page, 'basic');

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 272 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 158 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 272 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 158 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -14,8 +14,9 @@
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<script type="module">
import { alertController } from '../../../../dist/ionic/index.esm.js';
import { alertController, loadingController } from '../../../../dist/ionic/index.esm.js';
window.alertController = alertController;
window.loadingController = loadingController;
</script>
<body>
@@ -30,9 +31,12 @@
<ion-button id="basic" expand="block" onclick="presentAlert()">Alert</ion-button>
<ion-button id="longMessage" expand="block" onclick="presentAlertLongMessage()">Alert Long Message</ion-button>
<ion-button id="multipleButtons" expand="block" onclick="presentAlertMultipleButtons()"
>Multiple Buttons (>2)</ion-button
>
>Multiple Buttons (>2)
</ion-button>
<ion-button id="noMessage" expand="block" onclick="presentAlertNoMessage()">Alert No Message</ion-button>
<ion-button id="asyncHandler" expand="block" onclick="presentAlertAsyncHandler()"
>Alert Async Handler</ion-button
>
<ion-button id="confirm" expand="block" onclick="presentAlertConfirm()">Confirm</ion-button>
<ion-button id="prompt" expand="block" onclick="presentAlertPrompt()">Prompt</ion-button>
<ion-button id="radio" expand="block" onclick="presentAlertRadio()">Radio</ion-button>
@@ -46,6 +50,7 @@
--min-width: 0;
--max-width: 200px;
}
#delete-button {
color: #eb445a;
}
@@ -346,6 +351,30 @@
],
});
}
function presentAlertAsyncHandler() {
openAlert({
header: 'Alert',
message: 'This is an alert with async handlers',
buttons: [
{
text: 'Confirm',
handler: () => {
return new Promise(async (resolve) => {
const loading = await loadingController.create({
message: 'Please wait...',
});
await loading.present();
setTimeout(async () => {
await loading.dismiss();
resolve();
}, 1000);
});
},
},
],
});
}
</script>
</body>
</html>

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More