mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
feat(components): cascade mode from parent to child components (#19369)
fixes #18285
This commit is contained in:
@ -21,8 +21,8 @@
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<h2>Mode: ios</h2>
|
||||
<ion-segment mode="ios" id="modeSegment" name="iosMode" value="kittens">
|
||||
<h2>Mode: segment & button ios</h2>
|
||||
<ion-segment mode="ios" value="kittens">
|
||||
<ion-segment-button mode="ios" value="puppies">
|
||||
<ion-label>Puppies</ion-label>
|
||||
</ion-segment-button>
|
||||
@ -34,10 +34,21 @@
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<hr>
|
||||
<h2>Mode: segment ios</h2>
|
||||
<ion-segment mode="ios" value="kittens">
|
||||
<ion-segment-button value="puppies">
|
||||
<ion-label>Puppies</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="kittens">
|
||||
<ion-label>Kittens</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="turtles">
|
||||
<ion-label>Turtles</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<h2>Mode: md</h2>
|
||||
<ion-segment mode="md" name="mdMode" value="kittens">
|
||||
<h2>Mode: segment ios, button: md</h2>
|
||||
<ion-segment mode="ios" value="kittens">
|
||||
<ion-segment-button mode="md" value="puppies">
|
||||
<ion-label>Puppies</ion-label>
|
||||
</ion-segment-button>
|
||||
@ -48,6 +59,48 @@
|
||||
<ion-label>Turtles</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Mode: segment & button md</h2>
|
||||
<ion-segment mode="md" value="kittens">
|
||||
<ion-segment-button mode="md" value="puppies">
|
||||
<ion-label>Puppies</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button mode="md" value="kittens">
|
||||
<ion-label>Kittens</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button mode="md" value="turtles">
|
||||
<ion-label>Turtles</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
|
||||
<h2>Mode: segment md</h2>
|
||||
<ion-segment mode="md" value="kittens">
|
||||
<ion-segment-button value="puppies">
|
||||
<ion-label>Puppies</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="kittens">
|
||||
<ion-label>Kittens</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="turtles">
|
||||
<ion-label>Turtles</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<h2>Mode: segment md, button: ios</h2>
|
||||
<ion-segment mode="md" value="kittens">
|
||||
<ion-segment-button mode="ios" value="puppies">
|
||||
<ion-label>Puppies</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button mode="ios" value="kittens">
|
||||
<ion-label>Kittens</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button mode="ios" value="turtles">
|
||||
<ion-label>Turtles</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
57
core/src/components/title/title.ios.scss
Normal file
57
core/src/components/title/title.ios.scss
Normal file
@ -0,0 +1,57 @@
|
||||
@import "./title";
|
||||
|
||||
// iOS Title
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
@include position(0, null, null, 0);
|
||||
@include padding(0, 90px, 0);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
transform: translateZ(0);
|
||||
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
// iOS Title: Small
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.title-small) {
|
||||
@include padding(6px, 9px, 16px, 9px);
|
||||
|
||||
position: relative;
|
||||
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
// iOS Title: Large
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.title-large) {
|
||||
@include padding(0, 16px);
|
||||
|
||||
bottom: 0;
|
||||
|
||||
align-items: flex-end;
|
||||
|
||||
min-width: 100%;
|
||||
|
||||
padding-bottom: 6px;
|
||||
|
||||
font-size: 34px;
|
||||
font-weight: 700;
|
||||
|
||||
text-align: start;
|
||||
}
|
27
core/src/components/title/title.md.scss
Normal file
27
core/src/components/title/title.md.scss
Normal file
@ -0,0 +1,27 @@
|
||||
@import "./title";
|
||||
|
||||
// Material Design Title
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
@include padding(0, 20px);
|
||||
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
|
||||
letter-spacing: .0125em;
|
||||
}
|
||||
|
||||
|
||||
// Material Design Title: Small
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.title-small) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
font-size: 15px;
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
@ -19,35 +19,6 @@
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
:host(.title-ios.title-default),
|
||||
:host(.title-ios.title-large) {
|
||||
@include position(0, null, null, 0);
|
||||
@include padding(0, 90px, 0);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
transform: translateZ(0);
|
||||
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:host(.title-md) {
|
||||
@include padding(0, 20px);
|
||||
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
|
||||
letter-spacing: .0125em;
|
||||
}
|
||||
|
||||
:host(.ion-color) {
|
||||
color: #{current-color(base)};
|
||||
}
|
||||
@ -72,44 +43,3 @@
|
||||
:host(.title-small) .toolbar-title {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
:host(.title-ios.title-small) {
|
||||
@include padding(6px, 9px, 16px, 9px);
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
font-size: 13px;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:host(.title-md.title-small) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
font-size: 15px;
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
// Title: Large
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.title-ios.title-large) {
|
||||
@include padding(0, 16px);
|
||||
|
||||
bottom: 0;
|
||||
|
||||
align-items: flex-end;
|
||||
|
||||
min-width: 100%;
|
||||
|
||||
padding-bottom: 6px;
|
||||
|
||||
font-size: 34px;
|
||||
font-weight: 700;
|
||||
|
||||
text-align: start;
|
||||
}
|
||||
|
@ -6,7 +6,10 @@ import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-title',
|
||||
styleUrl: 'title.scss',
|
||||
styleUrls: {
|
||||
'ios': 'title.ios.scss',
|
||||
'md': 'title.md.scss'
|
||||
},
|
||||
shadow: true
|
||||
})
|
||||
export class ToolbarTitle implements ComponentInterface {
|
||||
@ -52,21 +55,14 @@ export class ToolbarTitle implements ComponentInterface {
|
||||
return (this.size !== undefined) ? this.size : 'default';
|
||||
}
|
||||
|
||||
private getMode() {
|
||||
const mode = getIonMode(this);
|
||||
const toolbar = this.el.closest('ion-toolbar');
|
||||
return (toolbar && toolbar.mode) || mode;
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = this.getMode();
|
||||
const mode = getIonMode(this);
|
||||
const size = this.getSize();
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[`title-${mode}`]: true,
|
||||
[`title-${size}`]: true,
|
||||
|
||||
...createColorClasses(this.color),
|
||||
|
19
core/src/components/toolbar/test/modes/e2e.ts
Normal file
19
core/src/components/toolbar/test/modes/e2e.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('toolbar: modes', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/toolbar/test/modes?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
|
||||
test('toolbar:rtl: modes', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/toolbar/test/modes?ionic:_testing=true&rtl=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
84
core/src/components/toolbar/test/modes/index.html
Normal file
84
core/src/components/toolbar/test/modes/index.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Toolbar - Modes</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-content id="content">
|
||||
<!-- iOS Toolbar -->
|
||||
<ion-toolbar mode="ios">
|
||||
<ion-title>iOS toolbar</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- Material Design Toolbar -->
|
||||
<ion-toolbar mode="md">
|
||||
<ion-title>MD toolbar</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- iOS Toolbar -->
|
||||
<ion-toolbar mode="ios">
|
||||
<ion-title>iOS toolbar</ion-title>
|
||||
|
||||
<ion-buttons slot="secondary">
|
||||
<ion-button fill="outline">Outline</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-buttons slot="primary">
|
||||
<ion-button>Clear</ion-button>
|
||||
<ion-button fill="solid">Solid</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- Material Design Toolbar -->
|
||||
<ion-toolbar mode="md">
|
||||
<ion-title>MD toolbar</ion-title>
|
||||
|
||||
<ion-buttons slot="secondary">
|
||||
<ion-button fill="outline">Outline</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-buttons slot="primary">
|
||||
<ion-button>Clear</ion-button>
|
||||
<ion-button fill="solid">Solid</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- iOS Toolbar -->
|
||||
<ion-toolbar mode="ios">
|
||||
<ion-searchbar></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- Material Design Toolbar -->
|
||||
<ion-toolbar mode="md">
|
||||
<ion-searchbar></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- iOS Toolbar -->
|
||||
<ion-toolbar mode="ios">
|
||||
<ion-segment>
|
||||
<ion-segment-button>iOS</ion-segment-button>
|
||||
<ion-segment-button checked>Segment</ion-segment-button>
|
||||
</ion-segment>
|
||||
</ion-toolbar>
|
||||
|
||||
<!-- Material Design Toolbar -->
|
||||
<ion-toolbar mode="md">
|
||||
<ion-segment>
|
||||
<ion-segment-button>MD</ion-segment-button>
|
||||
<ion-segment-button checked>Segment</ion-segment-button>
|
||||
</ion-segment>
|
||||
</ion-toolbar>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -7,10 +7,10 @@ import { config, configFromSession, configFromURL, saveConfig } from './config';
|
||||
|
||||
declare const Context: any;
|
||||
|
||||
let mode: Mode;
|
||||
let defaultMode: Mode;
|
||||
|
||||
export const getIonMode = (ref?: any): Mode => {
|
||||
return (ref && getMode(ref)) || mode;
|
||||
return (ref && getMode(ref)) || defaultMode;
|
||||
};
|
||||
|
||||
export default () => {
|
||||
@ -37,19 +37,28 @@ export default () => {
|
||||
}
|
||||
|
||||
// first see if the mode was set as an attribute on <html>
|
||||
// which could have been set by the user, or by prerendering
|
||||
// which could have been set by the user, or by pre-rendering
|
||||
// otherwise get the mode via config settings, and fallback to md
|
||||
Ionic.config = config;
|
||||
Ionic.mode = mode = config.get('mode', (doc.documentElement.getAttribute('mode')) || (isPlatform(win, 'ios') ? 'ios' : 'md'));
|
||||
config.set('mode', mode);
|
||||
doc.documentElement.setAttribute('mode', mode);
|
||||
doc.documentElement.classList.add(mode);
|
||||
Ionic.mode = defaultMode = config.get('mode', (doc.documentElement.getAttribute('mode')) || (isPlatform(win, 'ios') ? 'ios' : 'md'));
|
||||
config.set('mode', defaultMode);
|
||||
doc.documentElement.setAttribute('mode', defaultMode);
|
||||
doc.documentElement.classList.add(defaultMode);
|
||||
|
||||
if (config.getBoolean('_testing')) {
|
||||
config.set('animated', false);
|
||||
}
|
||||
|
||||
setMode(
|
||||
(elm: any) => (elm as any).mode = (elm as any).mode || elm.getAttribute('mode') || mode
|
||||
);
|
||||
setMode((elm: any) => {
|
||||
while (elm) {
|
||||
const elmMode = (elm as any).mode || elm.getAttribute('mode');
|
||||
|
||||
if (elmMode) {
|
||||
return elmMode;
|
||||
}
|
||||
|
||||
elm = elm.parentElement;
|
||||
}
|
||||
return defaultMode;
|
||||
});
|
||||
};
|
||||
|
Reference in New Issue
Block a user