diff --git a/core/package.json b/core/package.json
index 3afefe7cdb..d1dc6a2490 100644
--- a/core/package.json
+++ b/core/package.json
@@ -30,7 +30,7 @@
"loader/"
],
"dependencies": {
- "ionicons": "4.5.5"
+ "ionicons": "4.5.6"
},
"devDependencies": {
"@stencil/core": "0.17.3-0",
diff --git a/core/src/components/action-sheet/action-sheet.tsx b/core/src/components/action-sheet/action-sheet.tsx
index 0353ba39d7..bb90ea59c4 100644
--- a/core/src/components/action-sheet/action-sheet.tsx
+++ b/core/src/components/action-sheet/action-sheet.tsx
@@ -196,6 +196,8 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
zIndex: 20000 + this.overlayIndex,
},
class: {
+ [`${this.mode}`]: true,
+
...getClassMap(this.cssClass),
'action-sheet-translucent': this.translucent
}
diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx
index 75a54ea8ce..d3d0937f02 100644
--- a/core/src/components/alert/alert.tsx
+++ b/core/src/components/alert/alert.tsx
@@ -392,6 +392,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
},
class: {
...getClassMap(this.cssClass),
+ [`${this.mode}`]: true,
'alert-translucent': this.translucent
}
};
diff --git a/core/src/components/anchor/anchor.tsx b/core/src/components/anchor/anchor.tsx
index 8bc8f149e6..83a4833114 100644
--- a/core/src/components/anchor/anchor.tsx
+++ b/core/src/components/anchor/anchor.tsx
@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Listen, Prop } from '@stencil/core';
-import { Color, RouterDirection } from '../../interface';
+import { Color, Mode, RouterDirection } from '../../interface';
import { createColorClasses, openURL } from '../../utils/theme';
@Component({
@@ -9,6 +9,7 @@ import { createColorClasses, openURL } from '../../utils/theme';
shadow: true
})
export class Anchor implements ComponentInterface {
+ mode!: Mode;
@Prop({ context: 'window' }) win!: Window;
@@ -40,6 +41,7 @@ export class Anchor implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'ion-activatable': true
}
};
diff --git a/core/src/components/app/app.tsx b/core/src/components/app/app.tsx
index 22f18660fa..e9f45ea54c 100644
--- a/core/src/components/app/app.tsx
+++ b/core/src/components/app/app.tsx
@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Prop, QueueApi } from '@stencil/core';
-import { Config } from '../../interface';
+import { Config, Mode } from '../../interface';
import { rIC } from '../../utils/helpers';
import { isPlatform } from '../../utils/platform';
@@ -9,6 +9,7 @@ import { isPlatform } from '../../utils/platform';
styleUrl: 'app.scss'
})
export class App implements ComponentInterface {
+ mode!: Mode;
@Element() el!: HTMLElement;
@@ -34,6 +35,7 @@ export class App implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
'ion-page': true,
'force-statusbar-padding': this.config.getBoolean('_forceStatusbarPadding')
}
diff --git a/core/src/components/avatar/avatar.tsx b/core/src/components/avatar/avatar.tsx
index eef8f5913b..11afa2ee77 100644
--- a/core/src/components/avatar/avatar.tsx
+++ b/core/src/components/avatar/avatar.tsx
@@ -1,5 +1,7 @@
import { Component, ComponentInterface } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-avatar',
styleUrls: {
@@ -9,6 +11,15 @@ import { Component, ComponentInterface } from '@stencil/core';
shadow: true
})
export class Avatar implements ComponentInterface {
+ mode!: Mode;
+
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
render() {
return ;
diff --git a/core/src/components/back-button/back-button.tsx b/core/src/components/back-button/back-button.tsx
index 5f55176344..811e46055c 100644
--- a/core/src/components/back-button/back-button.tsx
+++ b/core/src/components/back-button/back-button.tsx
@@ -62,6 +62,7 @@ export class BackButton implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'button': true, // ion-buttons target .button
'ion-activatable': true,
diff --git a/core/src/components/backdrop/backdrop.tsx b/core/src/components/backdrop/backdrop.tsx
index bb2426155a..0e58abb40c 100644
--- a/core/src/components/backdrop/backdrop.tsx
+++ b/core/src/components/backdrop/backdrop.tsx
@@ -1,5 +1,6 @@
import { Component, ComponentInterface, Event, EventEmitter, Listen, Prop } from '@stencil/core';
+import { Mode } from '../../interface';
import { GESTURE_CONTROLLER } from '../../utils/gesture';
import { now } from '../../utils/helpers';
@@ -12,6 +13,7 @@ import { now } from '../../utils/helpers';
shadow: true
})
export class Backdrop implements ComponentInterface {
+ mode!: Mode;
private lastClick = -10000;
private blocker = GESTURE_CONTROLLER.createBlocker({
@@ -78,6 +80,7 @@ export class Backdrop implements ComponentInterface {
return {
tabindex: '-1',
class: {
+ [`${this.mode}`]: true,
'backdrop-hide': !this.visible,
'backdrop-no-tappable': !this.tappable,
}
diff --git a/core/src/components/badge/badge.tsx b/core/src/components/badge/badge.tsx
index 4e3fc8d5d4..8bcaa2d7e8 100644
--- a/core/src/components/badge/badge.tsx
+++ b/core/src/components/badge/badge.tsx
@@ -26,7 +26,10 @@ export class Badge implements ComponentInterface {
hostData() {
return {
- class: createColorClasses(this.color)
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true
+ }
};
}
diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx
index b4eed33c31..5618293b9f 100644
--- a/core/src/components/button/button.tsx
+++ b/core/src/components/button/button.tsx
@@ -148,6 +148,7 @@ export class Button implements ComponentInterface {
'aria-disabled': disabled ? 'true' : null,
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
[buttonType]: true,
[`${buttonType}-${expand}`]: expand !== undefined,
[`${buttonType}-${size}`]: size !== undefined,
diff --git a/core/src/components/buttons/buttons.tsx b/core/src/components/buttons/buttons.tsx
index a8f737a121..8f44eb8180 100644
--- a/core/src/components/buttons/buttons.tsx
+++ b/core/src/components/buttons/buttons.tsx
@@ -1,5 +1,7 @@
import { Component, ComponentInterface } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-buttons',
styleUrls: {
@@ -8,4 +10,14 @@ import { Component, ComponentInterface } from '@stencil/core';
},
scoped: true,
})
-export class Buttons implements ComponentInterface {}
+export class Buttons implements ComponentInterface {
+ mode!: Mode;
+
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true
+ }
+ };
+ }
+}
diff --git a/core/src/components/card-content/card-content.tsx b/core/src/components/card-content/card-content.tsx
index fff0a86337..fdc3aa10c6 100644
--- a/core/src/components/card-content/card-content.tsx
+++ b/core/src/components/card-content/card-content.tsx
@@ -1,7 +1,6 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
-import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-card-content',
@@ -19,7 +18,12 @@ export class CardContent implements ComponentInterface {
hostData() {
return {
- class: createThemedClasses(this.mode, 'card-content')
+ class: {
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`card-content-${this.mode}`]: true
+ }
};
}
}
diff --git a/core/src/components/card-header/card-header.tsx b/core/src/components/card-header/card-header.tsx
index 93b2965c5c..e210736558 100644
--- a/core/src/components/card-header/card-header.tsx
+++ b/core/src/components/card-header/card-header.tsx
@@ -34,6 +34,7 @@ export class CardHeader implements ComponentInterface {
class: {
...createColorClasses(this.color),
'card-header-translucent': this.translucent,
+ [`${this.mode}`]: true
}
};
}
diff --git a/core/src/components/card-subtitle/card-subtitle.tsx b/core/src/components/card-subtitle/card-subtitle.tsx
index 37b29d71af..7f1b6df0d3 100644
--- a/core/src/components/card-subtitle/card-subtitle.tsx
+++ b/core/src/components/card-subtitle/card-subtitle.tsx
@@ -26,7 +26,10 @@ export class CardSubtitle implements ComponentInterface {
hostData() {
return {
- class: createColorClasses(this.color),
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true
+ },
'role': 'heading',
'aria-level': '3'
};
diff --git a/core/src/components/card-title/card-title.tsx b/core/src/components/card-title/card-title.tsx
index 1fea16eaa0..231e0dd04f 100644
--- a/core/src/components/card-title/card-title.tsx
+++ b/core/src/components/card-title/card-title.tsx
@@ -26,7 +26,10 @@ export class CardTitle implements ComponentInterface {
hostData() {
return {
- class: createColorClasses(this.color),
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true
+ },
'role': 'heading',
'aria-level': '2'
};
diff --git a/core/src/components/card/card.tsx b/core/src/components/card/card.tsx
index 759e17eb44..a140e5e54e 100644
--- a/core/src/components/card/card.tsx
+++ b/core/src/components/card/card.tsx
@@ -27,7 +27,10 @@ export class Card implements ComponentInterface {
hostData() {
return {
- class: createColorClasses(this.color)
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true
+ }
};
}
}
diff --git a/core/src/components/checkbox/checkbox.tsx b/core/src/components/checkbox/checkbox.tsx
index a5c146fb51..4340f6f757 100644
--- a/core/src/components/checkbox/checkbox.tsx
+++ b/core/src/components/checkbox/checkbox.tsx
@@ -137,6 +137,7 @@ export class Checkbox implements ComponentInterface {
'aria-labelledby': labelId,
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
'in-item': hostContext('ion-item', el),
'checkbox-checked': checked,
'checkbox-disabled': disabled,
diff --git a/core/src/components/chip/chip.tsx b/core/src/components/chip/chip.tsx
index c174302595..69dea9e4fc 100644
--- a/core/src/components/chip/chip.tsx
+++ b/core/src/components/chip/chip.tsx
@@ -33,6 +33,7 @@ export class Chip implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'chip-outline': this.outline,
'ion-activatable': true,
}
diff --git a/core/src/components/col/col.tsx b/core/src/components/col/col.tsx
index d3bd78cea7..6f0daacf28 100644
--- a/core/src/components/col/col.tsx
+++ b/core/src/components/col/col.tsx
@@ -1,5 +1,6 @@
import { Component, ComponentInterface, Element, Listen, Prop } from '@stencil/core';
+import { Mode } from '../../interface';
import { matchBreakpoint } from '../../utils/media';
const win = window as any;
@@ -12,6 +13,8 @@ const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
shadow: true
})
export class Col implements ComponentInterface {
+ mode!: Mode;
+
@Prop({ context: 'window' }) win!: Window;
@Element() el!: HTMLStencilElement;
@@ -247,6 +250,9 @@ export class Col implements ComponentInterface {
hostData() {
const isRTL = this.win.document.dir === 'rtl';
return {
+ class: {
+ [`${this.mode}`]: true
+ },
style: {
...this.calculateOffset(isRTL),
...this.calculatePull(isRTL),
diff --git a/core/src/components/content/content.tsx b/core/src/components/content/content.tsx
index 2e0b17001a..513c88943b 100644
--- a/core/src/components/content/content.tsx
+++ b/core/src/components/content/content.tsx
@@ -293,6 +293,7 @@ export class Content implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'content-sizing': hostContext('ion-popover', this.el),
'overscroll': !!this.forceOverscroll,
},
diff --git a/core/src/components/datetime/datetime-util.spec.ts b/core/src/components/datetime/datetime-util.spec.ts
index f0b343f6d0..effe879e99 100644
--- a/core/src/components/datetime/datetime-util.spec.ts
+++ b/core/src/components/datetime/datetime-util.spec.ts
@@ -2,7 +2,7 @@ import { convertDataToISO, parseDate } from './datetime-util';
describe('datetime-util', () => {
describe('convertDataToISO', () => {
- it('prints an emptry string for an empty datetime', () => {
+ it('prints an empty string for an empty datetime', () => {
expect(convertDataToISO({})).toEqual('');
});
diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx
index 8c37a6adb2..c5af45ab9a 100644
--- a/core/src/components/datetime/datetime.tsx
+++ b/core/src/components/datetime/datetime.tsx
@@ -615,6 +615,7 @@ export class Datetime implements ComponentInterface {
'aria-haspopup': 'true',
'aria-labelledby': labelId,
class: {
+ [`${this.mode}`]: true,
'datetime-disabled': disabled,
'datetime-readonly': readonly,
'datetime-placeholder': addPlaceholderClass,
diff --git a/core/src/components/fab-button/fab-button.tsx b/core/src/components/fab-button/fab-button.tsx
index aa88f239ee..fc099e179a 100755
--- a/core/src/components/fab-button/fab-button.tsx
+++ b/core/src/components/fab-button/fab-button.tsx
@@ -95,6 +95,7 @@ export class FabButton implements ComponentInterface {
'aria-disabled': disabled ? 'true' : null,
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
'fab-button-in-list': inList,
'fab-button-translucent-in-list': inList && translucent,
'fab-button-close-active': activated,
diff --git a/core/src/components/fab-list/fab-list.tsx b/core/src/components/fab-list/fab-list.tsx
index 961c310723..2ce5e14a48 100644
--- a/core/src/components/fab-list/fab-list.tsx
+++ b/core/src/components/fab-list/fab-list.tsx
@@ -1,11 +1,15 @@
import { Component, ComponentInterface, Element, Prop, Watch } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-fab-list',
styleUrl: 'fab-list.scss',
shadow: true
})
export class FabList implements ComponentInterface {
+ mode!: Mode;
+
@Element() el!: HTMLIonFabElement;
/**
@@ -32,6 +36,7 @@ export class FabList implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
'fab-list-active': this.activated,
[`fab-list-side-${this.side}`]: true
}
diff --git a/core/src/components/fab/fab.tsx b/core/src/components/fab/fab.tsx
index 1cd86807fd..7ec8e97218 100644
--- a/core/src/components/fab/fab.tsx
+++ b/core/src/components/fab/fab.tsx
@@ -1,11 +1,14 @@
import { Component, ComponentInterface, Element, Listen, Method, Prop, Watch } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-fab',
styleUrl: 'fab.scss',
shadow: true
})
export class Fab implements ComponentInterface {
+ mode!: Mode;
@Element() el!: HTMLElement;
@@ -75,6 +78,7 @@ export class Fab implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
[`fab-horizontal-${this.horizontal}`]: this.horizontal !== undefined,
[`fab-vertical-${this.vertical}`]: this.vertical !== undefined,
'fab-edge': this.edge
diff --git a/core/src/components/footer/footer.tsx b/core/src/components/footer/footer.tsx
index 0a05abbb64..f2320c9996 100644
--- a/core/src/components/footer/footer.tsx
+++ b/core/src/components/footer/footer.tsx
@@ -1,7 +1,6 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
-import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-footer',
@@ -25,13 +24,15 @@ export class Footer implements ComponentInterface {
@Prop() translucent = false;
hostData() {
- const themedClasses = createThemedClasses(this.mode, 'footer');
- const translucentClasses = this.translucent ? createThemedClasses(this.mode, 'footer-translucent') : null;
-
return {
class: {
- ...themedClasses,
- ...translucentClasses
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`footer-${this.mode}`]: true,
+
+ [`footer-translucent`]: this.translucent,
+ [`footer-translucent-${this.mode}`]: this.translucent,
}
};
}
diff --git a/core/src/components/footer/test/translucent/e2e.ts b/core/src/components/footer/test/translucent/e2e.ts
new file mode 100644
index 0000000000..5ee2922356
--- /dev/null
+++ b/core/src/components/footer/test/translucent/e2e.ts
@@ -0,0 +1,14 @@
+import { newE2EPage } from '@stencil/core/testing';
+
+import { checkComponentModeClasses } from '../../../../utils/test/utils';
+
+test('footer: translucent', async () => {
+ const page = await newE2EPage({
+ url: '/src/components/footer/test/translucent?ionic:_testing=true'
+ });
+
+ await checkComponentModeClasses(await page.find('ion-footer'), 'footer-translucent');
+
+ const compare = await page.compareScreenshot();
+ expect(compare).toMatchScreenshot();
+});
diff --git a/core/src/components/grid/grid.tsx b/core/src/components/grid/grid.tsx
index 30ee66ac44..83833748b8 100644
--- a/core/src/components/grid/grid.tsx
+++ b/core/src/components/grid/grid.tsx
@@ -1,11 +1,14 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-grid',
styleUrl: 'grid.scss',
shadow: true
})
export class Grid implements ComponentInterface {
+ mode!: Mode;
/**
* If `true`, the grid will have a fixed width based on the screen size.
@@ -15,6 +18,7 @@ export class Grid implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
'grid-fixed': this.fixed
}
};
diff --git a/core/src/components/header/header.tsx b/core/src/components/header/header.tsx
index dc0de9f6fa..1cd2c7bd86 100644
--- a/core/src/components/header/header.tsx
+++ b/core/src/components/header/header.tsx
@@ -1,7 +1,6 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
-import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-header',
@@ -25,13 +24,15 @@ export class Header implements ComponentInterface {
@Prop() translucent = false;
hostData() {
- const themedClasses = createThemedClasses(this.mode, 'header');
- const translucentClasses = this.translucent ? createThemedClasses(this.mode, 'header-translucent') : null;
-
return {
class: {
- ...themedClasses,
- ...translucentClasses
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`header-${this.mode}`]: true,
+
+ [`header-translucent`]: this.translucent,
+ [`header-translucent-${this.mode}`]: this.translucent,
}
};
}
diff --git a/core/src/components/header/test/translucent/e2e.ts b/core/src/components/header/test/translucent/e2e.ts
new file mode 100644
index 0000000000..dcc2964855
--- /dev/null
+++ b/core/src/components/header/test/translucent/e2e.ts
@@ -0,0 +1,14 @@
+import { newE2EPage } from '@stencil/core/testing';
+
+import { checkComponentModeClasses } from '../../../../utils/test/utils';
+
+test('header: translucent', async () => {
+ const page = await newE2EPage({
+ url: '/src/components/header/test/translucent?ionic:_testing=true'
+ });
+
+ await checkComponentModeClasses(await page.find('ion-header'), 'header-translucent');
+
+ const compare = await page.compareScreenshot();
+ expect(compare).toMatchScreenshot();
+});
diff --git a/core/src/components/img/img.tsx b/core/src/components/img/img.tsx
index 9d43afc445..06c52cace3 100644
--- a/core/src/components/img/img.tsx
+++ b/core/src/components/img/img.tsx
@@ -1,11 +1,14 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-img',
styleUrl: 'img.scss',
shadow: true
})
export class Img implements ComponentInterface {
+ mode!: Mode;
private io?: IntersectionObserver;
@@ -81,6 +84,14 @@ export class Img implements ComponentInterface {
}
}
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
+
render() {
return (
,
diff --git a/core/src/components/modal/test/test.utils.ts b/core/src/components/modal/test/test.utils.ts
index 4a5a3f0816..4c5e772a89 100644
--- a/core/src/components/modal/test/test.utils.ts
+++ b/core/src/components/modal/test/test.utils.ts
@@ -19,18 +19,18 @@ export async function testModal(
await page.click(selector);
await page.waitForSelector(selector);
- let popover = await page.find('ion-modal');
- await popover.waitForVisible();
+ let modal = await page.find('ion-modal');
+ await modal.waitForVisible();
screenshotCompares.push(await page.compareScreenshot());
- await popover.callMethod('dismiss');
- await popover.waitForNotVisible();
+ await modal.callMethod('dismiss');
+ await modal.waitForNotVisible();
screenshotCompares.push(await page.compareScreenshot('dismiss'));
- popover = await page.find('ion-modal');
- expect(popover).toBeNull();
+ modal = await page.find('ion-modal');
+ expect(modal).toBeNull();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
diff --git a/core/src/components/note/note.tsx b/core/src/components/note/note.tsx
index 7fa26be73b..c2f7a8be42 100644
--- a/core/src/components/note/note.tsx
+++ b/core/src/components/note/note.tsx
@@ -26,7 +26,10 @@ export class Note implements ComponentInterface {
hostData() {
return {
- class: createColorClasses(this.color)
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true,
+ }
};
}
diff --git a/core/src/components/picker-column/picker-column.tsx b/core/src/components/picker-column/picker-column.tsx
index 7600d3d611..293174b0e0 100644
--- a/core/src/components/picker-column/picker-column.tsx
+++ b/core/src/components/picker-column/picker-column.tsx
@@ -349,6 +349,7 @@ export class PickerColumnCmp implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
'picker-col': true,
'picker-opts-left': this.col.align === 'left',
'picker-opts-right': this.col.align === 'right'
diff --git a/core/src/components/picker/picker.tsx b/core/src/components/picker/picker.tsx
index 68279289fe..510a82013f 100644
--- a/core/src/components/picker/picker.tsx
+++ b/core/src/components/picker/picker.tsx
@@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me
import { Animation, AnimationBuilder, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface, PickerButton, PickerColumn } from '../../interface';
import { dismiss, eventMethod, present } from '../../utils/overlays';
-import { createThemedClasses, getClassMap } from '../../utils/theme';
+import { getClassMap } from '../../utils/theme';
import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave';
@@ -204,7 +204,11 @@ export class Picker implements ComponentInterface, OverlayInterface {
return {
'aria-modal': 'true',
class: {
- ...createThemedClasses(this.mode, 'picker'),
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`picker-${this.mode}`]: true,
+
...getClassMap(this.cssClass)
},
style: {
diff --git a/core/src/components/popover/popover.tsx b/core/src/components/popover/popover.tsx
index 7f0af453ae..e9e354a905 100644
--- a/core/src/components/popover/popover.tsx
+++ b/core/src/components/popover/popover.tsx
@@ -205,6 +205,7 @@ export class Popover implements ComponentInterface, OverlayInterface {
},
class: {
...getClassMap(this.cssClass),
+ [`${this.mode}`]: true,
'popover-translucent': this.translucent
}
};
diff --git a/core/src/components/progress-bar/progress-bar.tsx b/core/src/components/progress-bar/progress-bar.tsx
index badd6d1fea..2c40643965 100644
--- a/core/src/components/progress-bar/progress-bar.tsx
+++ b/core/src/components/progress-bar/progress-bar.tsx
@@ -62,6 +62,7 @@ export class ProgressBar implements ComponentInterface {
'aria-valuemax': 1,
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
[`progress-bar-${type}`]: true,
'progress-paused': paused,
'progress-bar-reversed': document.dir === 'rtl' ? !reversed : reversed
diff --git a/core/src/components/radio-group/radio-group.tsx b/core/src/components/radio-group/radio-group.tsx
index 191528f480..004c4d43ac 100644
--- a/core/src/components/radio-group/radio-group.tsx
+++ b/core/src/components/radio-group/radio-group.tsx
@@ -1,11 +1,12 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Prop, Watch } from '@stencil/core';
-import { RadioGroupChangeEventDetail } from '../../interface';
+import { Mode, RadioGroupChangeEventDetail } from '../../interface';
@Component({
tag: 'ion-radio-group'
})
export class RadioGroup implements ComponentInterface {
+ mode!: Mode;
private inputId = `ion-rg-${radioGroupIds++}`;
private labelId = `${this.inputId}-lbl`;
@@ -122,7 +123,10 @@ export class RadioGroup implements ComponentInterface {
hostData() {
return {
'role': 'radiogroup',
- 'aria-labelledby': this.labelId
+ 'aria-labelledby': this.labelId,
+ class: {
+ [`${this.mode}`]: true,
+ }
};
}
}
diff --git a/core/src/components/radio/radio.tsx b/core/src/components/radio/radio.tsx
index 7096415770..84c644f476 100644
--- a/core/src/components/radio/radio.tsx
+++ b/core/src/components/radio/radio.tsx
@@ -163,6 +163,7 @@ export class Radio implements ComponentInterface {
'aria-labelledby': labelId,
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
'in-item': hostContext('ion-item', el),
'interactive': true,
'radio-checked': checked,
diff --git a/core/src/components/range/range.tsx b/core/src/components/range/range.tsx
index ce97a1e8a0..bd9a60ad7c 100644
--- a/core/src/components/range/range.tsx
+++ b/core/src/components/range/range.tsx
@@ -379,6 +379,7 @@ export class Range implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'in-item': hostContext('ion-item', this.el),
'range-disabled': this.disabled,
'range-pressed': this.pressedKnob !== undefined,
diff --git a/core/src/components/refresher-content/refresher-content.tsx b/core/src/components/refresher-content/refresher-content.tsx
index 4940ad58f4..2cbbd3ff17 100644
--- a/core/src/components/refresher-content/refresher-content.tsx
+++ b/core/src/components/refresher-content/refresher-content.tsx
@@ -43,6 +43,14 @@ export class RefresherContent implements ComponentInterface {
}
}
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
+
render() {
return [
diff --git a/core/src/components/refresher/refresher.tsx b/core/src/components/refresher/refresher.tsx
index da81476d6d..3341fdfb2e 100644
--- a/core/src/components/refresher/refresher.tsx
+++ b/core/src/components/refresher/refresher.tsx
@@ -1,7 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
import { Gesture, GestureDetail, Mode, RefresherEventDetail } from '../../interface';
-import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-refresher',
@@ -350,7 +349,10 @@ export class Refresher implements ComponentInterface {
return {
slot: 'fixed',
class: {
- ...createThemedClasses(this.mode, 'refresher'),
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`refresher-${this.mode}`]: true,
'refresher-active': this.state !== RefresherState.Inactive,
'refresher-pulling': this.state === RefresherState.Pulling,
diff --git a/core/src/components/reorder-group/reorder-group.tsx b/core/src/components/reorder-group/reorder-group.tsx
index 10fdc0f809..905781fa8f 100644
--- a/core/src/components/reorder-group/reorder-group.tsx
+++ b/core/src/components/reorder-group/reorder-group.tsx
@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
-import { Gesture, GestureDetail, ItemReorderEventDetail } from '../../interface';
+import { Gesture, GestureDetail, ItemReorderEventDetail, Mode } from '../../interface';
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '../../utils/haptic';
const enum ReorderGroupState {
@@ -14,6 +14,7 @@ const enum ReorderGroupState {
styleUrl: 'reorder-group.scss'
})
export class ReorderGroup implements ComponentInterface {
+ mode!: Mode;
private selectedItemEl?: HTMLElement;
private selectedItemHeight!: number;
@@ -293,6 +294,7 @@ export class ReorderGroup implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
'reorder-enabled': !this.disabled,
'reorder-list-active': this.state !== ReorderGroupState.Idle,
}
diff --git a/core/src/components/reorder/reorder.tsx b/core/src/components/reorder/reorder.tsx
index 2b4d3fd104..4391b4754c 100644
--- a/core/src/components/reorder/reorder.tsx
+++ b/core/src/components/reorder/reorder.tsx
@@ -20,6 +20,14 @@ export class Reorder implements ComponentInterface {
ev.stopImmediatePropagation();
}
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
+
render() {
return (
diff --git a/core/src/components/ripple-effect/ripple-effect.tsx b/core/src/components/ripple-effect/ripple-effect.tsx
index 0102167268..066967c45b 100644
--- a/core/src/components/ripple-effect/ripple-effect.tsx
+++ b/core/src/components/ripple-effect/ripple-effect.tsx
@@ -1,11 +1,14 @@
import { Component, ComponentInterface, Element, Method, Prop, QueueApi } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-ripple-effect',
styleUrl: 'ripple-effect.scss',
shadow: true
})
export class RippleEffect implements ComponentInterface {
+ mode!: Mode;
@Element() el!: HTMLElement;
@@ -79,6 +82,7 @@ export class RippleEffect implements ComponentInterface {
return {
role: 'presentation',
class: {
+ [`${this.mode}`]: true,
'unbounded': this.unbounded
}
};
diff --git a/core/src/components/row/row.tsx b/core/src/components/row/row.tsx
index 7b830a0d5d..c947353e6f 100644
--- a/core/src/components/row/row.tsx
+++ b/core/src/components/row/row.tsx
@@ -1,11 +1,22 @@
import { Component, ComponentInterface } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-row',
styleUrl: 'row.scss',
shadow: true
})
export class Row implements ComponentInterface {
+ mode!: Mode;
+
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
render() {
return ;
}
diff --git a/core/src/components/searchbar/searchbar.tsx b/core/src/components/searchbar/searchbar.tsx
index f8407f6f0e..1645a2b2aa 100644
--- a/core/src/components/searchbar/searchbar.tsx
+++ b/core/src/components/searchbar/searchbar.tsx
@@ -352,6 +352,7 @@ export class Searchbar implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'searchbar-animated': animated,
'searchbar-no-animate': animated && this.noAnimate,
'searchbar-has-value': (this.getValue() !== ''),
diff --git a/core/src/components/segment-button/segment-button.tsx b/core/src/components/segment-button/segment-button.tsx
index 271423fb22..b2fd6ea5a4 100644
--- a/core/src/components/segment-button/segment-button.tsx
+++ b/core/src/components/segment-button/segment-button.tsx
@@ -71,6 +71,7 @@ export class SegmentButton implements ComponentInterface {
return {
'aria-disabled': disabled ? 'true' : null,
class: {
+ [`${this.mode}`]: true,
'segment-button-has-label': hasLabel,
'segment-button-has-icon': hasIcon,
'segment-button-has-label-only': hasLabel && !hasIcon,
diff --git a/core/src/components/segment/segment.tsx b/core/src/components/segment/segment.tsx
index 4eb1284d38..aa29084562 100644
--- a/core/src/components/segment/segment.tsx
+++ b/core/src/components/segment/segment.tsx
@@ -99,6 +99,7 @@ export class Segment implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
+ [`${this.mode}`]: true,
'segment-disabled': this.disabled,
'segment-scrollable': this.scrollable
}
diff --git a/core/src/components/select-option/select-option.tsx b/core/src/components/select-option/select-option.tsx
index fbd15271b9..c855416642 100644
--- a/core/src/components/select-option/select-option.tsx
+++ b/core/src/components/select-option/select-option.tsx
@@ -1,11 +1,14 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-select-option',
shadow: true,
styleUrl: 'select-option.scss'
})
export class SelectOption implements ComponentInterface {
+ mode!: Mode;
private inputId = `ion-selopt-${selectOptionIds++}`;
@@ -55,7 +58,10 @@ export class SelectOption implements ComponentInterface {
hostData() {
return {
'role': 'option',
- 'id': this.inputId
+ 'id': this.inputId,
+ class: {
+ [`${this.mode}`]: true,
+ }
};
}
}
diff --git a/core/src/components/select-popover/select-popover.tsx b/core/src/components/select-popover/select-popover.tsx
index f167fe425c..d6e933d5e2 100644
--- a/core/src/components/select-popover/select-popover.tsx
+++ b/core/src/components/select-popover/select-popover.tsx
@@ -34,6 +34,14 @@ export class SelectPopover implements ComponentInterface {
}
}
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
+
render() {
return (
diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx
index ce1b3d59f3..4f42c5adfe 100644
--- a/core/src/components/select/select.tsx
+++ b/core/src/components/select/select.tsx
@@ -455,6 +455,7 @@ export class Select implements ComponentInterface {
'aria-haspopup': 'dialog',
'aria-labelledby': labelId,
class: {
+ [`${this.mode}`]: true,
'in-item': hostContext('ion-item', this.el),
'select-disabled': this.disabled,
}
diff --git a/core/src/components/skeleton-text/skeleton-text.tsx b/core/src/components/skeleton-text/skeleton-text.tsx
index 9dde1e234b..56872b14f3 100644
--- a/core/src/components/skeleton-text/skeleton-text.tsx
+++ b/core/src/components/skeleton-text/skeleton-text.tsx
@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Prop } from '@stencil/core';
-import { Config } from '../../interface';
+import { Config, Mode } from '../../interface';
import { hostContext } from '../../utils/theme';
@Component({
@@ -9,6 +9,7 @@ import { hostContext } from '../../utils/theme';
shadow: true
})
export class SkeletonText implements ComponentInterface {
+ mode!: Mode;
@Element() el!: HTMLElement;
@@ -49,6 +50,7 @@ export class SkeletonText implements ComponentInterface {
return {
class: {
+ [`${this.mode}`]: true,
'skeleton-text-animated': animated,
'in-media': inMedia
},
diff --git a/core/src/components/slide/slide.tsx b/core/src/components/slide/slide.tsx
index 0033f3c51c..b165a42c89 100644
--- a/core/src/components/slide/slide.tsx
+++ b/core/src/components/slide/slide.tsx
@@ -1,11 +1,14 @@
import { Component, ComponentInterface, Event } from '@stencil/core';
import { EventEmitter } from 'ionicons/dist/types/stencil.core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-slide',
styleUrl: 'slide.scss'
})
export class Slide implements ComponentInterface {
+ mode!: Mode;
/** @internal */
@Event() ionSlideChanged!: EventEmitter;
@@ -21,6 +24,7 @@ export class Slide implements ComponentInterface {
hostData() {
return {
class: {
+ [`${this.mode}`]: true,
'swiper-slide': true,
'swiper-zoom-container': true
}
diff --git a/core/src/components/slides/slides.scss b/core/src/components/slides/slides.scss
index 13db253731..bd36fe27fd 100644
--- a/core/src/components/slides/slides.scss
+++ b/core/src/components/slides/slides.scss
@@ -4,7 +4,7 @@
// Slides
// --------------------------------------------------
-.slides {
+ion-slides {
/**
* @prop --bullet-background: Background of the pagination bullets
* @prop --bullet-background-active: Background of the active pagination bullet
diff --git a/core/src/components/slides/slides.tsx b/core/src/components/slides/slides.tsx
index 7b481dcc5c..097539c780 100644
--- a/core/src/components/slides/slides.tsx
+++ b/core/src/components/slides/slides.tsx
@@ -2,7 +2,6 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me
import { Mode } from '../../interface';
import { rIC } from '../../utils/helpers.js';
-import { createThemedClasses } from '../../utils/theme.js';
import { SwiperInterface, SwiperOptions } from './swiper/swiper-interface';
@@ -450,7 +449,11 @@ export class Slides implements ComponentInterface {
hostData() {
return {
class: {
- ...createThemedClasses(this.mode, 'slides'),
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`slides-${this.mode}`]: true,
+
'swiper-container': true
}
};
diff --git a/core/src/components/spinner/spinner.tsx b/core/src/components/spinner/spinner.tsx
index 02c6f50a10..a5d065672d 100644
--- a/core/src/components/spinner/spinner.tsx
+++ b/core/src/components/spinner/spinner.tsx
@@ -50,7 +50,7 @@ export class Spinner implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
-
+ [`${this.mode}`]: true,
[`spinner-${this.getName()}`]: true,
'spinner-paused': !!this.paused || this.config.getBoolean('_testing')
}
diff --git a/core/src/components/split-pane/split-pane.scss b/core/src/components/split-pane/split-pane.scss
index df991481ea..5ae038afcd 100644
--- a/core/src/components/split-pane/split-pane.scss
+++ b/core/src/components/split-pane/split-pane.scss
@@ -3,7 +3,7 @@
// Split Pane
// --------------------------------------------------
-.split-pane {
+ion-split-pane {
/**
* @prop --border: Border between panes
*/
diff --git a/core/src/components/split-pane/split-pane.tsx b/core/src/components/split-pane/split-pane.tsx
index 37624af1b3..841f41daff 100644
--- a/core/src/components/split-pane/split-pane.tsx
+++ b/core/src/components/split-pane/split-pane.tsx
@@ -1,7 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core';
import { Mode } from '../../interface';
-import { createThemedClasses } from '../../utils/theme';
const SPLIT_PANE_MAIN = 'split-pane-main';
const SPLIT_PANE_SIDE = 'split-pane-side';
@@ -165,7 +164,11 @@ export class SplitPane implements ComponentInterface {
hostData() {
return {
class: {
- ...createThemedClasses(this.mode, 'split-pane'),
+ [`${this.mode}`]: true,
+
+ // Used internally for styling
+ [`split-pane-${this.mode}`]: true,
+
'split-pane-visible': this.visible
}
};
diff --git a/core/src/components/tab-bar/tab-bar.tsx b/core/src/components/tab-bar/tab-bar.tsx
index f89ef68294..5f6480eb25 100644
--- a/core/src/components/tab-bar/tab-bar.tsx
+++ b/core/src/components/tab-bar/tab-bar.tsx
@@ -74,6 +74,7 @@ export class TabBar implements ComponentInterface {
'aria-hidden': keyboardVisible ? 'true' : null,
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
'tab-bar-translucent': translucent,
'tab-bar-hidden': keyboardVisible,
}
diff --git a/core/src/components/tab-button/tab-button.tsx b/core/src/components/tab-button/tab-button.tsx
index f1e5143900..cb86c0e1bc 100644
--- a/core/src/components/tab-button/tab-button.tsx
+++ b/core/src/components/tab-button/tab-button.tsx
@@ -96,6 +96,7 @@ export class TabButton implements ComponentInterface {
'aria-selected': selected ? 'true' : null,
'id': tab !== undefined ? `tab-button-${tab}` : null,
class: {
+ [`${this.mode}`]: true,
'tab-selected': selected,
'tab-disabled': disabled,
'tab-has-label': hasLabel,
diff --git a/core/src/components/tabs/test/standalone/e2e.ts b/core/src/components/tabs/test/standalone/e2e.ts
new file mode 100644
index 0000000000..69a7bb857e
--- /dev/null
+++ b/core/src/components/tabs/test/standalone/e2e.ts
@@ -0,0 +1,26 @@
+import { newE2EPage } from '@stencil/core/testing';
+
+test('tabs: standalone', async () => {
+ const page = await newE2EPage({
+ url: '/src/components/tabs/test/standalone?ionic:_testing=true'
+ });
+
+ const compares = [];
+
+ // Initial page load
+ compares.push(await page.compareScreenshot());
+
+ let tabButton = await page.find('#tab-button-tab-one');
+ await tabButton.click();
+
+ compares.push(await page.compareScreenshot(`tab one`));
+
+ tabButton = await page.find('#tab-button-tab-two');
+ await tabButton.click();
+
+ compares.push(await page.compareScreenshot(`tab two`));
+
+ for (const compare of compares) {
+ expect(compare).toMatchScreenshot();
+ }
+});
diff --git a/core/src/components/tabs/test/vanilla/index.html b/core/src/components/tabs/test/standalone/index.html
similarity index 56%
rename from core/src/components/tabs/test/vanilla/index.html
rename to core/src/components/tabs/test/standalone/index.html
index 76fe94d145..d38c4b065b 100644
--- a/core/src/components/tabs/test/vanilla/index.html
+++ b/core/src/components/tabs/test/standalone/index.html
@@ -3,7 +3,7 @@
- Tab - Vanilla
+ Tabs - Standalone
@@ -14,14 +14,24 @@
-
+
- Div One
+
+
Tab One
+
- Div Two
+
+
Tab Two
+
+
+
+
+
+
Tab Three
+
@@ -34,23 +44,41 @@
Tab Two
+
+
+ Tab Three
+
+
+
+
diff --git a/core/src/components/tabs/test/vanilla/e2e.js b/core/src/components/tabs/test/vanilla/e2e.js
deleted file mode 100644
index 5a6131a049..0000000000
--- a/core/src/components/tabs/test/vanilla/e2e.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// 'use strict';
-
-// const { register, Page, platforms } = require('../../../../../scripts/e2e');
-// const { getElement, waitAndGetElementById, waitForTransition } = require('../../../../../scripts/e2e/utils');
-
-// class E2ETestPage extends Page {
-// constructor(driver, platform) {
-// super(driver, `http://localhost:3333/src/components/tabs/test/vanilla?ionic:mode=${platform}`);
-// }
-// }
-
-// platforms.forEach(platform => {
-// describe('tabs/vanilla', () => {
-// register('should init', driver => {
-// const page = new E2ETestPage(driver, platform);
-// return page.navigate();
-// });
-
-// register('should check each tab', async (driver, testContext) => {
-// testContext.timeout(60000);
-// const page = new E2ETestPage(driver, platform);
-
-// await waitForTransition(300);
-
-// const tabTwoButton = await waitAndGetElementById(driver, 'tab-t-0-1');
-// tabTwoButton.click();
-// await waitForTransition(600);
-
-// const tabThreeButton = await waitAndGetElementById(driver, 'tab-t-0-2');
-// tabThreeButton.click();
-// await waitForTransition(600);
-// });
-// });
-// });
diff --git a/core/src/components/text/text.tsx b/core/src/components/text/text.tsx
index 6b41464ab8..455c3c2f61 100644
--- a/core/src/components/text/text.tsx
+++ b/core/src/components/text/text.tsx
@@ -24,7 +24,10 @@ export class Text implements ComponentInterface {
hostData() {
return {
- class: createColorClasses(this.color)
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true,
+ }
};
}
diff --git a/core/src/components/textarea/textarea.tsx b/core/src/components/textarea/textarea.tsx
index 97bcf96812..13dd1fe41a 100644
--- a/core/src/components/textarea/textarea.tsx
+++ b/core/src/components/textarea/textarea.tsx
@@ -266,7 +266,10 @@ export class Textarea implements ComponentInterface {
hostData() {
return {
'aria-disabled': this.disabled ? 'true' : null,
- class: createColorClasses(this.color)
+ class: {
+ ...createColorClasses(this.color),
+ [`${this.mode}`]: true,
+ }
};
}
diff --git a/core/src/components/thumbnail/thumbnail.tsx b/core/src/components/thumbnail/thumbnail.tsx
index 8b1198d555..0ca03bbb01 100644
--- a/core/src/components/thumbnail/thumbnail.tsx
+++ b/core/src/components/thumbnail/thumbnail.tsx
@@ -1,11 +1,22 @@
import { Component, ComponentInterface } from '@stencil/core';
+import { Mode } from '../../interface';
+
@Component({
tag: 'ion-thumbnail',
styleUrl: 'thumbnail.scss',
shadow: true
})
export class Thumbnail implements ComponentInterface {
+ mode!: Mode;
+
+ hostData() {
+ return {
+ class: {
+ [`${this.mode}`]: true,
+ }
+ };
+ }
render() {
return ;
}
diff --git a/core/src/components/title/title.scss b/core/src/components/title/title.scss
index 08b463e62d..16f6c949cc 100644
--- a/core/src/components/title/title.scss
+++ b/core/src/components/title/title.scss
@@ -62,4 +62,4 @@
overflow: hidden;
pointer-events: auto;
-}
+}
\ No newline at end of file
diff --git a/core/src/components/title/title.tsx b/core/src/components/title/title.tsx
index ceff504083..9962970214 100644
--- a/core/src/components/title/title.tsx
+++ b/core/src/components/title/title.tsx
@@ -28,10 +28,13 @@ export class ToolbarTitle implements ComponentInterface {
hostData() {
const mode = this.getMode();
+
return {
class: {
+ [`${mode}`]: true,
+ [`title-${mode}`]: true,
+
...createColorClasses(this.color),
- [`title-${mode}`]: true
}
};
}
diff --git a/core/src/components/toast/toast.tsx b/core/src/components/toast/toast.tsx
index 1d3a6ad682..3a160d4f6f 100644
--- a/core/src/components/toast/toast.tsx
+++ b/core/src/components/toast/toast.tsx
@@ -226,6 +226,8 @@ export class Toast implements ComponentInterface, OverlayInterface {
zIndex: 60000 + this.overlayIndex,
},
class: {
+ [`${this.mode}`]: true,
+
...createColorClasses(this.color),
...getClassMap(this.cssClass),
'toast-translucent': this.translucent
diff --git a/core/src/components/toggle/toggle.tsx b/core/src/components/toggle/toggle.tsx
index dd5989e440..9fa7f38b14 100644
--- a/core/src/components/toggle/toggle.tsx
+++ b/core/src/components/toggle/toggle.tsx
@@ -195,6 +195,7 @@ export class Toggle implements ComponentInterface {
class: {
...createColorClasses(color),
+ [`${this.mode}`]: true,
'in-item': hostContext('ion-item', el),
'toggle-activated': activated,
'toggle-checked': checked,
diff --git a/core/src/components/toolbar/toolbar.tsx b/core/src/components/toolbar/toolbar.tsx
index b1e5e0fa6c..ade3ad61e4 100644
--- a/core/src/components/toolbar/toolbar.tsx
+++ b/core/src/components/toolbar/toolbar.tsx
@@ -72,8 +72,10 @@ export class Toolbar implements ComponentInterface {
return {
class: {
+ [`${this.mode}`]: true,
+
...childStyles,
- ...createColorClasses(this.color)
+ ...createColorClasses(this.color),
}
};
}
diff --git a/core/src/utils/test/modes/e2e.ts b/core/src/utils/test/modes/e2e.ts
new file mode 100644
index 0000000000..0ff2fb66d8
--- /dev/null
+++ b/core/src/utils/test/modes/e2e.ts
@@ -0,0 +1,74 @@
+import { newE2EPage } from '@stencil/core/testing';
+
+import { checkComponentModeClasses, checkModeClasses } from '../utils';
+
+// This test is to loop through all components that should have
+// specific classes added and test them
+test('component: modes', async () => {
+ const page = await newE2EPage({
+ url: '/src/utils/test/modes?ionic:_testing=true'
+ });
+
+ // First test: .button class
+ // ----------------------------------------------------------------
+ // components that need to have the `button` class
+ // for use in styling by other components (`ion-buttons`)
+ // e.g.
+ let tags = ['ion-button', 'ion-back-button', 'ion-menu-button'];
+
+ for (const tag of tags) {
+ const el = await page.find(tag);
+ expect(el).toHaveClass('button');
+ }
+
+ // Second test: .item class
+ // ----------------------------------------------------------------
+ // components that need to have the `item` class
+ // for use in styling by other components
+ // e.g.
+ tags = ['ion-item', 'ion-item-divider', 'ion-item-group'];
+
+ for (const tag of tags) {
+ const el = await page.find(tag);
+ expect(el).toHaveClass('item');
+ }
+
+ // Third test: .{component}-{mode} class
+ // ----------------------------------------------------------------
+ // components that need to have their tag name
+ // + mode as a class for internal styling
+ // e.g.
+ tags = ['ion-card-content', 'ion-footer', 'ion-header', 'ion-infinite-scroll-content', 'ion-item-group', 'ion-item-options', 'ion-list', 'ion-picker', 'ion-refresher', 'ion-slides', 'ion-split-pane'];
+
+ for (const tag of tags) {
+ const el = await page.find(tag);
+ await checkComponentModeClasses(el);
+ }
+
+ // Fourth test: .{mode} class
+ // ----------------------------------------------------------------
+ // components that need to have the mode class
+ // added for external / user styling
+ // e.g.
+ tags = ['ion-action-sheet', 'ion-alert', 'ion-anchor', 'ion-app', 'ion-avatar', 'ion-back-button', 'ion-backdrop', 'ion-badge', 'ion-button', 'ion-buttons', 'ion-card-content', 'ion-card-header', 'ion-card-subtitle', 'ion-card-title', 'ion-card', 'ion-checkbox', 'ion-chip', 'ion-col', 'ion-content', 'ion-datetime', 'ion-fab', 'ion-fab-button', 'ion-fab-list', 'ion-footer', 'ion-grid', 'ion-header', 'ion-icon', 'ion-img', 'ion-infinite-scroll', 'ion-infinite-scroll-content', 'ion-input', 'ion-item', 'ion-item-divider', 'ion-item-group', 'ion-item-option', 'ion-item-options', 'ion-item-sliding', 'ion-label', 'ion-list', 'ion-list-header', 'ion-loading', 'ion-modal', 'ion-menu', 'ion-menu-button', 'ion-menu-toggle', 'ion-note', 'ion-picker', 'ion-picker-column', 'ion-popover', 'ion-progress-bar', 'ion-radio', 'ion-radio-group', 'ion-range', 'ion-refresher', 'ion-refresher-content', 'ion-reorder', 'ion-reorder-group', 'ion-ripple-effect', 'ion-row', 'ion-searchbar', 'ion-segment', 'ion-segment-button', 'ion-select', 'ion-select-option', 'ion-select-popover', 'ion-skeleton-text', 'ion-slide', 'ion-slides', 'ion-spinner', 'ion-split-pane', 'ion-tab-bar', 'ion-tab-button', 'ion-text', 'ion-textarea', 'ion-thumbnail', 'ion-title', 'ion-toast', 'ion-toggle', 'ion-toolbar'];
+
+ for (const tag of tags) {
+ await page.waitForSelector(tag);
+ const el = await page.find(tag);
+ await checkModeClasses(el);
+ }
+
+ // Fifth test: changing mode
+ // ----------------------------------------------------------------
+ // change the mode on a button and then check the classes
+ // make sure it has the new mode and not the old mode
+ // e.g.
+ const button = await page.find('ion-button');
+ const mode = await button.getProperty('mode');
+
+ button.setAttribute('mode', 'blah');
+ await page.waitForChanges();
+
+ expect(button).not.toHaveClass(`${mode}`);
+ expect(button).toHaveClass(`blah`);
+});
diff --git a/core/src/utils/test/modes/index.html b/core/src/utils/test/modes/index.html
new file mode 100644
index 0000000000..b9262540e3
--- /dev/null
+++ b/core/src/utils/test/modes/index.html
@@ -0,0 +1,176 @@
+
+
+
+
+
+ Components - Modes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Components: Modes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/src/utils/test/utils.ts b/core/src/utils/test/utils.ts
index af51a59cfd..77508b3ba7 100644
--- a/core/src/utils/test/utils.ts
+++ b/core/src/utils/test/utils.ts
@@ -1,4 +1,4 @@
-import { E2EPage } from '@stencil/core/testing';
+import { E2EElement, E2EPage } from '@stencil/core/testing';
import { ElementHandle } from 'puppeteer';
export function generateE2EUrl(component: string, type: string, rtl = false): string {
@@ -112,3 +112,39 @@ export async function queryDeep(page: E2EPage, ...selectors: string[]): Promise<
if (parentElement) { resolve(parentElement); }
});
}
+
+/**
+ * Given an element and optional selector, use the selector if
+ * it exists or get the node name of that element if not. Combine
+ * with the current mode to verify the correct classes exist.
+ *
+ * @param el: E2EElement - The element to verify classes on
+ * @param selector: string - A selector to use instead of the element tag name
+ *
+ * Examples:
+ * await checkComponentModeClasses(await page.find('ion-card-content'))
+ * => expect(el).toHaveClass(`card-content-{mode}`);
+ *
+ * await checkComponentModeClasses(await page.find('ion-card-content'), 'some-class')
+ * => expect(el).toHaveClass(`some-class-{mode}`);
+ */
+export async function checkComponentModeClasses(el: E2EElement, selector?: string) {
+ // If passed a selector to use, use that, else grab the nodeName
+ // of the element and remove the ion prefix to get the class selector
+ const component = selector !== undefined ? selector : el.nodeName.toLowerCase().replace('ion-', '');
+
+ const mode = await el.getProperty('mode');
+
+ expect(el).toHaveClass(`${component}-${mode}`);
+}
+
+/**
+ * Given an element, get the mode and verify it exists as a class
+ *
+ * @param el: E2EElement - the element to verify the mode class on
+ */
+export async function checkModeClasses(el: E2EElement) {
+ const mode = await el.getProperty('mode');
+
+ expect(el).toHaveClass(`${mode}`);
+}
diff --git a/core/src/utils/theme.ts b/core/src/utils/theme.ts
index 1a2b10ceb8..b732243c33 100644
--- a/core/src/utils/theme.ts
+++ b/core/src/utils/theme.ts
@@ -1,4 +1,4 @@
-import { Color, CssClassMap, Mode, RouterDirection } from '../interface';
+import { Color, CssClassMap, RouterDirection } from '../interface';
export function hostContext(selector: string, el: HTMLElement): boolean {
return el.closest(selector) !== null;
@@ -14,13 +14,6 @@ export function createColorClasses(color: Color | undefined | null): CssClassMap
} : undefined;
}
-export function createThemedClasses(mode: Mode | undefined, name: string): CssClassMap {
- return {
- [name]: true,
- [`${name}-${mode}`]: mode !== undefined
- };
-}
-
export function getClassList(classes: string | (string | null | undefined)[] | undefined): string[] {
if (classes !== undefined) {
const array = Array.isArray(classes) ? classes : classes.split(' ');