fix(all): Ionic components that use child Ionic components are now correctly defined (#24191)

resolves #23571, #24116, #24129

Co-authored-by: Liam DeBeasi <liamdebeasi@icloud.com>
This commit is contained in:
Will Martin
2021-11-11 12:18:38 -05:00
committed by GitHub
parent 5d4f5af360
commit 5a2a335784
9 changed files with 104 additions and 34 deletions

35
core/package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "6.0.0-rc.2",
"license": "MIT",
"dependencies": {
"@stencil/core": "~2.10.0",
"@stencil/core": "~2.11.0-0",
"ionicons": "^6.0.0",
"tslib": "^2.1.0"
},
@ -1364,9 +1364,10 @@
"dev": true
},
"node_modules/@stencil/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.10.0.tgz",
"integrity": "sha512-15rWMTPQ/sp0lSV82HVCXkIya3QLN+uBl7pqK4JnTrp4HiLrzLmNbWjbvgCs55gw0lULbCIGbRIEsFz+Pe/Q+A==",
"version": "2.11.0-0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.11.0-0.tgz",
"integrity": "sha512-ZJlambyk3s5Xzqd5yfzwvD7adEIHpfv89yOd210XsMhonXOLHK2k7XpFluGYUrv69HDgosu2TjFxQxhyVSS0Vg==",
"license": "MIT",
"bin": {
"stencil": "bin/stencil"
},
@ -5556,6 +5557,19 @@
"@stencil/core": "~2.10.0"
}
},
"node_modules/ionicons/node_modules/@stencil/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.10.0.tgz",
"integrity": "sha512-15rWMTPQ/sp0lSV82HVCXkIya3QLN+uBl7pqK4JnTrp4HiLrzLmNbWjbvgCs55gw0lULbCIGbRIEsFz+Pe/Q+A==",
"license": "MIT",
"bin": {
"stencil": "bin/stencil"
},
"engines": {
"node": ">=12.10.0",
"npm": ">=6.0.0"
}
},
"node_modules/ip-regex": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
@ -15029,9 +15043,9 @@
"dev": true
},
"@stencil/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.10.0.tgz",
"integrity": "sha512-15rWMTPQ/sp0lSV82HVCXkIya3QLN+uBl7pqK4JnTrp4HiLrzLmNbWjbvgCs55gw0lULbCIGbRIEsFz+Pe/Q+A=="
"version": "2.11.0-0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.11.0-0.tgz",
"integrity": "sha512-ZJlambyk3s5Xzqd5yfzwvD7adEIHpfv89yOd210XsMhonXOLHK2k7XpFluGYUrv69HDgosu2TjFxQxhyVSS0Vg=="
},
"@stencil/react-output-target": {
"version": "0.1.0",
@ -18412,6 +18426,13 @@
"integrity": "sha512-p83W1T8jZUlllHAjuIWaDQbI36OYqdrwcf8MhYbKW7+9rjGlCMP9+5OaR0W7tl0QfM004uAiy/zkc7HTpDNKgA==",
"requires": {
"@stencil/core": "~2.10.0"
},
"dependencies": {
"@stencil/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.10.0.tgz",
"integrity": "sha512-15rWMTPQ/sp0lSV82HVCXkIya3QLN+uBl7pqK4JnTrp4HiLrzLmNbWjbvgCs55gw0lULbCIGbRIEsFz+Pe/Q+A=="
}
}
},
"ip-regex": {

View File

@ -31,7 +31,7 @@
"loader/"
],
"dependencies": {
"@stencil/core": "~2.10.0",
"@stencil/core": "~2.11.0-0",
"ionicons": "^6.0.0",
"tslib": "^2.1.0"
},

View File

@ -133,7 +133,7 @@ export class PickerColumnInternal implements ComponentInterface {
private inputModeChange = (ev: PickerInternalCustomEvent) => {
if (!this.numericInput) { return; }
const { inputMode, inputModeColumn } = ev.detail;
const { useInputMode, inputModeColumn } = ev.detail;
/**
* If inputModeColumn is undefined then this means
@ -141,7 +141,7 @@ export class PickerColumnInternal implements ComponentInterface {
*/
const isColumnActive = inputModeColumn === undefined || inputModeColumn === this.el;
if (!inputMode || !isColumnActive) {
if (!useInputMode || !isColumnActive) {
this.isActive = false;
return;
}

View File

@ -1,5 +1,5 @@
export interface PickerInternalChangeEventDetail {
inputMode: boolean;
useInputMode: boolean;
inputModeColumn?: HTMLIonPickerColumnInternalElement;
}

View File

@ -18,7 +18,7 @@ import { PickerInternalChangeEventDetail } from './picker-internal-interfaces';
})
export class PickerInternal implements ComponentInterface {
private inputEl?: HTMLInputElement;
private inputMode = false;
private useInputMode = false;
private inputModeColumn?: HTMLIonPickerColumnInternalElement;
private highlightEl?: HTMLElement;
private actionOnClick?: () => void;
@ -131,7 +131,7 @@ export class PickerInternal implements ComponentInterface {
* runs and runs the actionOnClick callback.
*/
private onPointerDown = (ev: PointerEvent) => {
const { inputMode, inputModeColumn, el } = this;
const { useInputMode, inputModeColumn, el } = this;
if (this.isInHighlightBounds(ev)) {
/**
* If we were already in
@ -140,7 +140,7 @@ export class PickerInternal implements ComponentInterface {
* should switch to input mode for
* that specific column.
*/
if (inputMode) {
if (useInputMode) {
/**
* If we tapped a picker column
* then we should either switch to input
@ -225,7 +225,7 @@ export class PickerInternal implements ComponentInterface {
* are eligible for text entry.
* (i.e. hour and minute columns)
*/
this.inputMode = true;
this.useInputMode = true;
this.inputModeColumn = columnEl;
/**
@ -253,10 +253,10 @@ export class PickerInternal implements ComponentInterface {
}
private exitInputMode = () => {
const { inputEl, inputMode } = this;
if (!inputMode || !inputEl) { return; }
const { inputEl, useInputMode } = this;
if (!useInputMode || !inputEl) { return; }
this.inputMode = false;
this.useInputMode = false;
this.inputModeColumn = undefined;
inputEl.blur();
inputEl.value = '';
@ -457,8 +457,8 @@ export class PickerInternal implements ComponentInterface {
* to select
*/
private onInputChange = () => {
const { inputMode, inputEl, inputModeColumn } = this;
if (!inputMode || !inputEl) { return; }
const { useInputMode, inputEl, inputModeColumn } = this;
if (!useInputMode || !inputEl) { return; }
if (inputModeColumn) {
this.selectSingleColumn();
@ -473,10 +473,10 @@ export class PickerInternal implements ComponentInterface {
* or not their column is "active" for text input.
*/
private emitInputModeChange = () => {
const { inputMode, inputModeColumn } = this;
const { useInputMode, inputModeColumn } = this;
this.ionInputModeChange.emit({
inputMode,
useInputMode,
inputModeColumn
});
}

View File

@ -1428,6 +1428,29 @@ Type: `Promise<any>`
| `--placeholder-opacity` | Opacity of the select placeholder text |
## Dependencies
### Depends on
- ion-select-popover
### Graph
```mermaid
graph TD;
ion-select --> ion-select-popover
ion-select-popover --> ion-item
ion-select-popover --> ion-checkbox
ion-select-popover --> ion-label
ion-select-popover --> ion-radio-group
ion-select-popover --> ion-radio
ion-select-popover --> ion-list
ion-select-popover --> ion-list-header
ion-item --> ion-icon
ion-item --> ion-ripple-effect
ion-item --> ion-note
style ion-select fill:#f9f,stroke:#333,stroke-width:4px
```
----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)*

View File

@ -360,6 +360,16 @@ export class Select implements ComponentInterface {
options: this.createPopoverOptions(this.childOpts, value)
}
};
/**
* Workaround for Stencil to autodefine ion-select-popover.
*/
// tslint:disable-next-line
if (false) {
// @ts-ignore
document.createElement('ion-select-popover');
}
return popoverController.create(popoverOpts);
}

View File

@ -1,3 +1,10 @@
import { ActionSheet } from '../components/action-sheet/action-sheet';
import { Alert } from '../components/alert/alert';
import { Loading } from '../components/loading/loading';
import { Modal } from '../components/modal/modal';
import { Picker } from '../components/picker/picker';
import { Popover } from '../components/popover/popover';
import { Toast } from '../components/toast/toast';
import { config } from '../global/config';
import { getIonMode } from '../global/ionic-global';
import { ActionSheetOptions, AlertOptions, Animation, AnimationBuilder, BackButtonEvent, HTMLIonOverlayElement, IonicConfig, LoadingOptions, ModalOptions, OverlayInterface, PickerOptions, PopoverOptions, ToastOptions } from '../interface';
@ -9,10 +16,10 @@ let lastId = 0;
export const activeAnimations = new WeakMap<OverlayInterface, Animation[]>();
const createController = <Opts extends object, HTMLElm extends any>(tagName: string) => {
const createController = <Opts extends object, HTMLElm extends any>(tagName: string, customElement?: any) => {
return {
create(options: Opts): Promise<HTMLElm> {
return createOverlay(tagName, options) as any;
return createOverlay(tagName, options, customElement) as any;
},
dismiss(data?: any, role?: string, id?: string) {
return dismissOverlay(document, data, role, tagName, id);
@ -23,13 +30,13 @@ const createController = <Opts extends object, HTMLElm extends any>(tagName: str
};
};
export const alertController = /*@__PURE__*/createController<AlertOptions, HTMLIonAlertElement>('ion-alert');
export const actionSheetController = /*@__PURE__*/createController<ActionSheetOptions, HTMLIonActionSheetElement>('ion-action-sheet');
export const loadingController = /*@__PURE__*/createController<LoadingOptions, HTMLIonLoadingElement>('ion-loading');
export const modalController = /*@__PURE__*/createController<ModalOptions, HTMLIonModalElement>('ion-modal');
export const pickerController = /*@__PURE__*/createController<PickerOptions, HTMLIonPickerElement>('ion-picker');
export const popoverController = /*@__PURE__*/createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover');
export const toastController = /*@__PURE__*/createController<ToastOptions, HTMLIonToastElement>('ion-toast');
export const alertController = /*@__PURE__*/createController<AlertOptions, HTMLIonAlertElement>('ion-alert', Alert);
export const actionSheetController = /*@__PURE__*/createController<ActionSheetOptions, HTMLIonActionSheetElement>('ion-action-sheet', ActionSheet);
export const loadingController = /*@__PURE__*/createController<LoadingOptions, HTMLIonLoadingElement>('ion-loading', Loading);
export const modalController = /*@__PURE__*/createController<ModalOptions, HTMLIonModalElement>('ion-modal', Modal);
export const pickerController = /*@__PURE__*/createController<PickerOptions, HTMLIonPickerElement>('ion-picker', Picker);
export const popoverController = /*@__PURE__*/createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover', Popover);
export const toastController = /*@__PURE__*/createController<ToastOptions, HTMLIonToastElement>('ion-toast', Toast);
export const prepareOverlay = <T extends HTMLIonOverlayElement>(el: T) => {
/* tslint:disable-next-line */
@ -43,10 +50,18 @@ export const prepareOverlay = <T extends HTMLIonOverlayElement>(el: T) => {
}
};
export const createOverlay = <T extends HTMLIonOverlayElement>(tagName: string, opts: object | undefined): Promise<T> => {
export const createOverlay = <T extends HTMLIonOverlayElement>(tagName: string, opts: object | undefined, customElement?: any): Promise<T> => {
/* tslint:disable-next-line */
if (typeof customElements !== 'undefined') {
return customElements.whenDefined(tagName).then(() => {
if (typeof window.customElements !== 'undefined') {
if (
typeof (window as any) !== 'undefined' &&
window.customElements &&
!window.customElements.get(tagName)
) {
window.customElements.define(tagName, customElement);
}
return window.customElements.whenDefined(tagName).then(() => {
const element = document.createElement(tagName) as HTMLIonOverlayElement;
element.classList.add('overlay-hidden');

View File

@ -157,6 +157,7 @@ export const config: Config = {
{
type: 'dist-custom-elements',
dir: 'components',
autoDefineCustomElements: true,
copy: [{
src: '../scripts/custom-elements',
dest: 'components',