fix(overlays): define children custom elements (#24372)

Resolves #24366
This commit is contained in:
Sean Perkins
2021-12-10 16:32:12 -05:00
committed by GitHub
parent 500985ce04
commit 7c700b4caa

View File

@ -2,6 +2,7 @@ import { ActionSheet } from '../components/action-sheet/action-sheet';
import { Alert } from '../components/alert/alert'; import { Alert } from '../components/alert/alert';
import { Loading } from '../components/loading/loading'; import { Loading } from '../components/loading/loading';
import { Modal } from '../components/modal/modal'; import { Modal } from '../components/modal/modal';
import { PickerColumnCmp } from '../components/picker-column/picker-column';
import { Picker } from '../components/picker/picker'; import { Picker } from '../components/picker/picker';
import { Popover } from '../components/popover/popover'; import { Popover } from '../components/popover/popover';
import { Toast } from '../components/toast/toast'; import { Toast } from '../components/toast/toast';
@ -16,10 +17,15 @@ 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, customElement?: any) => { type ChildCustomElementDefinition = {
tagName: string;
customElement: any;
}
const createController = <Opts extends object, HTMLElm extends any>(tagName: string, customElement?: any, childrenCustomElements?: ChildCustomElementDefinition[]) => {
return { return {
create(options: Opts): Promise<HTMLElm> { create(options: Opts): Promise<HTMLElm> {
return createOverlay(tagName, options, customElement) as any; return createOverlay(tagName, options, customElement, childrenCustomElements) 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);
@ -34,7 +40,7 @@ export const alertController = /*@__PURE__*/createController<AlertOptions, HTMLI
export const actionSheetController = /*@__PURE__*/createController<ActionSheetOptions, HTMLIonActionSheetElement>('ion-action-sheet', ActionSheet); export const actionSheetController = /*@__PURE__*/createController<ActionSheetOptions, HTMLIonActionSheetElement>('ion-action-sheet', ActionSheet);
export const loadingController = /*@__PURE__*/createController<LoadingOptions, HTMLIonLoadingElement>('ion-loading', Loading); export const loadingController = /*@__PURE__*/createController<LoadingOptions, HTMLIonLoadingElement>('ion-loading', Loading);
export const modalController = /*@__PURE__*/createController<ModalOptions, HTMLIonModalElement>('ion-modal', Modal); export const modalController = /*@__PURE__*/createController<ModalOptions, HTMLIonModalElement>('ion-modal', Modal);
export const pickerController = /*@__PURE__*/createController<PickerOptions, HTMLIonPickerElement>('ion-picker', Picker); export const pickerController = /*@__PURE__*/createController<PickerOptions, HTMLIonPickerElement>('ion-picker', Picker, [{ tagName: 'ion-picker-column', customElement: PickerColumnCmp }]);
export const popoverController = /*@__PURE__*/createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover', Popover); export const popoverController = /*@__PURE__*/createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover', Popover);
export const toastController = /*@__PURE__*/createController<ToastOptions, HTMLIonToastElement>('ion-toast', Toast); export const toastController = /*@__PURE__*/createController<ToastOptions, HTMLIonToastElement>('ion-toast', Toast);
@ -50,16 +56,25 @@ export const prepareOverlay = <T extends HTMLIonOverlayElement>(el: T) => {
} }
}; };
export const createOverlay = <T extends HTMLIonOverlayElement>(tagName: string, opts: object | undefined, customElement?: any): Promise<T> => { export const createOverlay = <T extends HTMLIonOverlayElement>(tagName: string, opts: object | undefined, customElement?: any, childrenCustomElements?: ChildCustomElementDefinition[]): Promise<T> => {
/* tslint:disable-next-line */ /* tslint:disable-next-line */
if (typeof window.customElements !== 'undefined') { if (typeof window.customElements !== 'undefined') {
if ( if (typeof (window as any) !== 'undefined' && window.customElements) {
typeof (window as any) !== 'undefined' && if (!window.customElements.get(tagName)) {
window.customElements &&
!window.customElements.get(tagName)
) {
window.customElements.define(tagName, customElement); window.customElements.define(tagName, customElement);
} }
/**
* If the parent element has nested usage of custom elements,
* we need to manually define those custom elements.
*/
if (childrenCustomElements) {
for (const customElementDefinition of childrenCustomElements) {
if (!window.customElements.get(customElementDefinition.tagName)) {
window.customElements.define(customElementDefinition.tagName, customElementDefinition.customElement);
}
}
}
}
return window.customElements.whenDefined(tagName).then(() => { return window.customElements.whenDefined(tagName).then(() => {
const element = document.createElement(tagName) as HTMLIonOverlayElement; const element = document.createElement(tagName) as HTMLIonOverlayElement;