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

View File

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

View File

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

View File

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

View File

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

View File

@ -1428,6 +1428,29 @@ Type: `Promise<any>`
| `--placeholder-opacity` | Opacity of the select placeholder text | | `--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/)* *Built with [StencilJS](https://stenciljs.com/)*

View File

@ -360,6 +360,16 @@ export class Select implements ComponentInterface {
options: this.createPopoverOptions(this.childOpts, value) 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); 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 { config } from '../global/config';
import { getIonMode } from '../global/ionic-global'; import { getIonMode } from '../global/ionic-global';
import { ActionSheetOptions, AlertOptions, Animation, AnimationBuilder, BackButtonEvent, HTMLIonOverlayElement, IonicConfig, LoadingOptions, ModalOptions, OverlayInterface, PickerOptions, PopoverOptions, ToastOptions } from '../interface'; 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[]>(); 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 { return {
create(options: Opts): Promise<HTMLElm> { 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) { dismiss(data?: any, role?: string, id?: string) {
return dismissOverlay(document, data, role, tagName, id); 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 alertController = /*@__PURE__*/createController<AlertOptions, HTMLIonAlertElement>('ion-alert', Alert);
export const actionSheetController = /*@__PURE__*/createController<ActionSheetOptions, HTMLIonActionSheetElement>('ion-action-sheet'); export const actionSheetController = /*@__PURE__*/createController<ActionSheetOptions, HTMLIonActionSheetElement>('ion-action-sheet', ActionSheet);
export const loadingController = /*@__PURE__*/createController<LoadingOptions, HTMLIonLoadingElement>('ion-loading'); export const loadingController = /*@__PURE__*/createController<LoadingOptions, HTMLIonLoadingElement>('ion-loading', Loading);
export const modalController = /*@__PURE__*/createController<ModalOptions, HTMLIonModalElement>('ion-modal'); export const modalController = /*@__PURE__*/createController<ModalOptions, HTMLIonModalElement>('ion-modal', Modal);
export const pickerController = /*@__PURE__*/createController<PickerOptions, HTMLIonPickerElement>('ion-picker'); export const pickerController = /*@__PURE__*/createController<PickerOptions, HTMLIonPickerElement>('ion-picker', Picker);
export const popoverController = /*@__PURE__*/createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover'); export const popoverController = /*@__PURE__*/createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover', Popover);
export const toastController = /*@__PURE__*/createController<ToastOptions, HTMLIonToastElement>('ion-toast'); export const toastController = /*@__PURE__*/createController<ToastOptions, HTMLIonToastElement>('ion-toast', Toast);
export const prepareOverlay = <T extends HTMLIonOverlayElement>(el: T) => { export const prepareOverlay = <T extends HTMLIonOverlayElement>(el: T) => {
/* tslint:disable-next-line */ /* 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 */ /* tslint:disable-next-line */
if (typeof customElements !== 'undefined') { if (typeof window.customElements !== 'undefined') {
return customElements.whenDefined(tagName).then(() => { 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; const element = document.createElement(tagName) as HTMLIonOverlayElement;
element.classList.add('overlay-hidden'); element.classList.add('overlay-hidden');

View File

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