Skip to content

Commit 30218e6

Browse files
author
Tanner Reits
committed
feat(config): add appRootSelector to initialize options
1 parent 3b5c419 commit 30218e6

File tree

9 files changed

+31
-10
lines changed

9 files changed

+31
-10
lines changed

core/api.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ ion-infinite-scroll-content,prop,theme,"ios" | "md" | "ionic",undefined,false,fa
884884

885885
ion-input,scoped
886886
ion-input,prop,autocapitalize,string,'off',false,false
887-
ion-input,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
887+
ion-input,prop,autocomplete,"name" | "url" | "off" | "on" | "additional-name" | "address-level1" | "address-level2" | "address-level3" | "address-level4" | "address-line1" | "address-line2" | "address-line3" | "bday-day" | "bday-month" | "bday-year" | "cc-csc" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-family-name" | "cc-given-name" | "cc-name" | "cc-number" | "cc-type" | "country" | "country-name" | "current-password" | "family-name" | "given-name" | "honorific-prefix" | "honorific-suffix" | "new-password" | "one-time-code" | "organization" | "postal-code" | "street-address" | "transaction-amount" | "transaction-currency" | "username" | "email" | "tel" | "tel-area-code" | "tel-country-code" | "tel-extension" | "tel-local" | "tel-national" | "nickname" | "organization-title" | "cc-additional-name" | "language" | "bday" | "sex" | "impp" | "photo",'off',false,false
888888
ion-input,prop,autocorrect,"off" | "on",'off',false,false
889889
ion-input,prop,autofocus,boolean,false,false,false
890890
ion-input,prop,clearInput,boolean,false,false,false
@@ -1867,7 +1867,7 @@ ion-row,prop,theme,"ios" | "md" | "ionic",undefined,false,false
18671867
ion-searchbar,scoped
18681868
ion-searchbar,prop,animated,boolean,false,false,false
18691869
ion-searchbar,prop,autocapitalize,string,'off',false,false
1870-
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
1870+
ion-searchbar,prop,autocomplete,"name" | "url" | "off" | "on" | "additional-name" | "address-level1" | "address-level2" | "address-level3" | "address-level4" | "address-line1" | "address-line2" | "address-line3" | "bday-day" | "bday-month" | "bday-year" | "cc-csc" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-family-name" | "cc-given-name" | "cc-name" | "cc-number" | "cc-type" | "country" | "country-name" | "current-password" | "family-name" | "given-name" | "honorific-prefix" | "honorific-suffix" | "new-password" | "one-time-code" | "organization" | "postal-code" | "street-address" | "transaction-amount" | "transaction-currency" | "username" | "email" | "tel" | "tel-area-code" | "tel-country-code" | "tel-extension" | "tel-local" | "tel-national" | "nickname" | "organization-title" | "cc-additional-name" | "language" | "bday" | "sex" | "impp" | "photo",'off',false,false
18711871
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
18721872
ion-searchbar,prop,cancelButtonIcon,string | undefined,undefined,false,false
18731873
ion-searchbar,prop,cancelButtonText,string,'Cancel',false,false

core/src/components/content/content.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { isPlatform } from '@utils/platform';
66
import { isRTL } from '@utils/rtl';
77
import { createColorClasses, hostContext } from '@utils/theme';
88

9+
import { config } from '../../global/config';
910
import { getIonMode, getIonTheme } from '../../global/ionic-global';
1011
import type { Color, Mode } from '../../interface';
1112

@@ -518,7 +519,8 @@ const getPageElement = (el: HTMLElement) => {
518519
* between the popover and the edges of the screen. But if the popover contains
519520
* its own page element, we should use that instead.
520521
*/
521-
const page = el.closest('ion-app, ion-page, .ion-page, page-inner, .popover-content');
522+
const appRootSelector = config.get('appRootSelector', 'ion-app');
523+
const page = el.closest(`${appRootSelector}, ion-page, .ion-page, page-inner, .popover-content`);
522524
if (page) {
523525
return page;
524526
}

core/src/components/footer/footer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { findIonContent, getScrollElement, printIonContentErrorMsg } from '@util
44
import type { KeyboardController } from '@utils/keyboard/keyboard-controller';
55
import { createKeyboardController } from '@utils/keyboard/keyboard-controller';
66

7+
import { config } from '../../global/config';
78
import { getIonTheme } from '../../global/ionic-global';
89

910
import { handleFooterFade } from './footer.utils';
@@ -86,7 +87,8 @@ export class Footer implements ComponentInterface {
8687
this.destroyCollapsibleFooter();
8788

8889
if (hasFade) {
89-
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
90+
const appRootSelector = config.get('appRootSelector', 'ion-app');
91+
const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
9092
const contentEl = pageEl ? findIonContent(pageEl) : null;
9193

9294
if (!contentEl) {

core/src/components/header/header.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { Attributes } from '@utils/helpers';
55
import { inheritAriaAttributes } from '@utils/helpers';
66
import { hostContext } from '@utils/theme';
77

8+
import { config } from '../../global/config';
89
import { getIonTheme } from '../../global/ionic-global';
910

1011
import {
@@ -92,7 +93,8 @@ export class Header implements ComponentInterface {
9293
this.destroyCollapsibleHeader();
9394

9495
if (hasCondense) {
95-
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
96+
const appRootSelector = config.get('appRootSelector', 'ion-app');
97+
const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
9698
const contentEl = pageEl ? findIonContent(pageEl) : null;
9799

98100
// Cloned elements are always needed in iOS transition
@@ -104,7 +106,7 @@ export class Header implements ComponentInterface {
104106

105107
await this.setupCondenseHeader(contentEl, pageEl);
106108
} else if (hasFade) {
107-
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
109+
const pageEl = this.el.closest('ion-app,.ion-app,ion-page,.ion-page,page-inner');
108110
const contentEl = pageEl ? findIonContent(pageEl) : null;
109111

110112
if (!contentEl) {

core/src/utils/config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ export interface IonicConfig {
124124
*/
125125
toastDuration?: number;
126126

127+
/**
128+
* The selector that will be used to query the root of the Ionic application.
129+
* This element is used for things like injecting overlay elements into the DOM and managing focus.
130+
*
131+
* @default 'ion-app'
132+
*/
133+
appRootSelector?: string;
134+
127135
/**
128136
* Overrides the toggle icon for all `ion-accordion` components.
129137
*/

core/src/utils/framework-delegate.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { config } from '../global/config';
12
import type { ComponentRef, FrameworkDelegate } from '../interface';
23

34
import { componentOnReady } from './helpers';
@@ -128,7 +129,8 @@ export const CoreDelegate = () => {
128129
* Get the root of the app and
129130
* add the overlay there.
130131
*/
131-
const app = document.querySelector('ion-app') || document.body;
132+
const appRootSelector = config.get('appRootSelector', 'ion-app');
133+
const app = document.querySelector(appRootSelector) || document.body;
132134

133135
/**
134136
* Create a placeholder comment so that

core/src/utils/helpers.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { EventEmitter } from '@stencil/core';
22

33
import type { Side } from '../components/menu/menu-interface';
4+
import { config } from '../global/config';
45

56
// TODO(FW-2832): types
67

@@ -266,7 +267,8 @@ export const focusVisibleElement = (el: HTMLElement) => {
266267
* which will let us explicitly set the elements to focus.
267268
*/
268269
if (el.classList.contains('ion-focusable')) {
269-
const app = el.closest('ion-app');
270+
const appRootSelector = config.get('appRootSelector', 'ion-app');
271+
const app = el.closest(appRootSelector) as HTMLIonAppElement | null;
270272
if (app) {
271273
app.setFocus([el]);
272274
}

core/src/utils/keyboard/keyboard-controller.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { doc, win } from '@utils/browser';
22

3+
import { config } from '../../global/config';
34
import { Keyboard, KeyboardResize } from '../native/keyboard';
45

56
/**
@@ -25,7 +26,8 @@ const getResizeContainer = (resizeMode?: KeyboardResize): HTMLElement | null =>
2526
* on that. In the event `ion-app` is not available then
2627
* we can fall back to `body`.
2728
*/
28-
const ionApp = doc.querySelector('ion-app');
29+
const appRootSelector = config.get('appRootSelector', 'ion-app');
30+
const ionApp = doc.querySelector(appRootSelector) as HTMLIonAppElement | null;
2931

3032
return ionApp ?? doc.body;
3133
};

core/src/utils/overlays.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,8 @@ export const dismiss = async <OverlayDismissOptions>(
697697
};
698698

699699
const getAppRoot = (doc: Document) => {
700-
return doc.querySelector('ion-app') || doc.body;
700+
const appRootSelector = config.get('appRootSelector', 'ion-app');
701+
return doc.querySelector(appRootSelector) || doc.body;
701702
};
702703

703704
const overlayAnimation = async (

0 commit comments

Comments
 (0)