refactor(components): update to use shadow DOM and work with css variables

- updates components to use shadow DOM or scoped if they require css variables
- moves global styles to an external stylesheet that needs to be imported
- adds support for additional colors and removes the Sass loops to generate colors for each component
- several property renames, bug fixes, and test updates

Co-authored-by: Manu Mtz.-Almeida <manu.mtza@gmail.com>
Co-authored-by: Adam Bradley <adambradley25@gmail.com>
Co-authored-by: Cam Wiegert <cam@camwiegert.com>
This commit is contained in:
Brandy Carney
2018-07-09 12:57:21 -04:00
parent a4659f03b4
commit a7f1f4daa7
710 changed files with 21327 additions and 21181 deletions

View File

@ -0,0 +1,15 @@
@import "./content";
@import "./content.ios.vars";
// iOS Content
// --------------------------------------------------
:host {
font-family: $content-ios-font-family;
}
::slotted(hr) {
height: $hairlines-width;
background-color: rgba(var(--ion-text-color-rgb, $text-color-rgb), $content-ios-horizontal-rule-background-color-alpha);
}

View File

@ -0,0 +1,13 @@
@import "../../themes/ionic.globals.ios";
// iOS Content
// --------------------------------------------------
/// @prop - Font family of the content
$content-ios-font-family: $font-family-base !default;
/// @prop - Background color of the outer content
$content-ios-outer-background: $background-color-step-50 !default;
/// @prop - Alpha for the Horizontal Rule
$content-ios-horizontal-rule-background-color-alpha: .12 !default;

View File

@ -0,0 +1,13 @@
@import "./content";
@import "./content.md.vars";
// Material Design Content
// --------------------------------------------------
:host {
font-family: $content-md-font-family;
}
::slotted(hr) {
background-color: $background-color-step-50;
}

View File

@ -0,0 +1,7 @@
@import "../../themes/ionic.globals.md";
// Material Design Content
// --------------------------------------------------
/// @prop - Font family of the content
$content-md-font-family: $font-family-base !default;

View File

@ -1,22 +1,49 @@
@import "../../themes/ionic.globals";
@import "../../themes/ionic.theme.default";
// Content
// --------------------------------------------------
ion-content {
:host {
position: relative;
display: block;
flex: 1;
width: 100%;
height: 100%;
color: #{current-color(contrast)};
background-color: #{current-color(base)};
contain: layout size style;
margin: 0 !important; // scss-lint:disable all
padding: 0 !important; // scss-lint:disable all
> .scroll-inner {
min-height: 100%;
}
--ion-color-base: #{$background-color};
--ion-color-contrast: #{$text-color};
--padding-top: 0;
--padding-bottom: 0;
--padding-start: 0;
--padding-end: 0;
--keyboard-offset: 0px;
}
:host(.ion-color-outer),
:host(.outer-content) {
--ion-color-base: #{$background-color-step-50};
}
.scroll-inner {
@include padding(
var(--padding-top),
var(--padding-end),
calc(var(--padding-bottom) + var(--keyboard-offset)),
var(--padding-start)
);
min-height: 100%;
box-sizing: border-box;
-webkit-margin-collapse: discard;
}

View File

@ -1,10 +1,15 @@
import { Component, Element, Listen, Method, Prop } from '@stencil/core';
import { Color, Config, Mode, QueueController } from '../../interface';
import { Component, Element, Listen, Method, Prop, QueueApi } from '@stencil/core';
import { Color, Config, Mode } from '../../interface';
import { createColorClasses } from '../../utils/theme';
@Component({
tag: 'ion-content',
styleUrl: 'content.scss'
styleUrls: {
ios: 'content.ios.scss',
md: 'content.md.scss'
},
shadow: true
})
export class Content {
@ -14,12 +19,12 @@ export class Content {
private scrollEl?: HTMLIonScrollElement;
mode!: Mode;
color?: Color;
@Prop() color?: Color;
@Element() el!: HTMLElement;
@Prop({ context: 'config' }) config!: Config;
@Prop({ context: 'queue' }) queue!: QueueController;
@Prop({ context: 'queue' }) queue!: QueueApi;
/**
* If true, the content will scroll behind the headers
@ -35,8 +40,16 @@ export class Content {
*/
@Prop() forceOverscroll?: boolean;
/**
* By default `ion-content` uses an `ion-scroll` under the hood to implement scrolling,
* if you want to disable the content scrolling for a given page, set this property to `false`.
*/
@Prop() scrollEnabled = true;
/**
* Because of performance reasons, ionScroll events are disabled by default, in order to enable them
* and start listening from (ionScroll), set this property to `true`.
*/
@Prop() scrollEvents = false;
@Listen('body:ionNavDidChange')
@ -52,55 +65,11 @@ export class Content {
this.scrollEl = undefined as any;
}
/**
* Scroll to the top of the content component.
*
* Duration of the scroll animation in milliseconds. Defaults to `300`.
* Returns a promise which is resolved when the scroll has completed.
*/
@Method()
scrollToTop(duration = 300) {
if (!this.scrollEl) {
throw new Error('content is not scrollable');
}
return this.scrollEl.scrollToTop(duration);
getScrollElement(): HTMLIonScrollElement {
return this.scrollEl!;
}
/**
* Scroll to the bottom of the content component.
*
* Duration of the scroll animation in milliseconds. Defaults to `300`.
* Returns a promise which is resolved when the scroll has completed.
*/
@Method()
scrollToBottom(duration = 300) {
if (!this.scrollEl) {
throw new Error('content is not scrollable');
}
return this.scrollEl.scrollToBottom(duration);
}
/**
* Scroll by a specific X/Y distance
*/
@Method()
scrollByPoint(x: number, y: number, duration: number, done?: Function): Promise<any> {
if (!this.scrollEl) {
throw new Error('content is not scrollable');
}
return this.scrollEl.scrollByPoint(x, y, duration, done);
}
/**
* Scroll to a specific X/Y coordinate in the content
*/
@Method()
scrollToPoint(x: number, y: number, duration: number, done?: Function): Promise<any> {
if (!this.scrollEl) {
throw new Error('content is not scrollable');
}
return this.scrollEl.scrollToPoint(x, y, duration, done);
}
private resize() {
if (!this.scrollEl) {
@ -137,9 +106,17 @@ export class Content {
}
}
hostData() {
return {
class: createColorClasses(this.color)
};
}
render() {
this.resize();
const innerScroll = <div class="scroll-inner"><slot></slot></div>;
return [
(this.scrollEnabled)
? <ion-scroll
@ -147,9 +124,9 @@ export class Content {
mode={this.mode}
scrollEvents={this.scrollEvents}
forceOverscroll={this.forceOverscroll}>
<slot></slot>
{ innerScroll }
</ion-scroll>
: <div class="scroll-inner"><slot></slot></div>,
: innerScroll,
<slot name="fixed"></slot>
];
}

View File

@ -9,6 +9,11 @@ view component.
## Properties
#### color
string
#### forceOverscroll
boolean
@ -31,14 +36,25 @@ to transparent.
boolean
By default `ion-content` uses an `ion-scroll` under the hood to implement scrolling,
if you want to disable the content scrolling for a given page, set this property to `false`.
#### scrollEvents
boolean
Because of performance reasons, ionScroll events are disabled by default, in order to enable them
and start listening from (ionScroll), set this property to `true`.
## Attributes
#### color
string
#### force-overscroll
boolean
@ -61,38 +77,21 @@ to transparent.
boolean
By default `ion-content` uses an `ion-scroll` under the hood to implement scrolling,
if you want to disable the content scrolling for a given page, set this property to `false`.
#### scroll-events
boolean
## Methods
#### scrollByPoint()
Scroll by a specific X/Y distance
#### scrollToBottom()
Scroll to the bottom of the content component.
Duration of the scroll animation in milliseconds. Defaults to `300`.
Returns a promise which is resolved when the scroll has completed.
Because of performance reasons, ionScroll events are disabled by default, in order to enable them
and start listening from (ionScroll), set this property to `true`.
#### scrollToPoint()
Scroll to a specific X/Y coordinate in the content
#### scrollToTop()
Scroll to the top of the content component.
## Methods
Duration of the scroll animation in milliseconds. Defaults to `300`.
Returns a promise which is resolved when the scroll has completed.
#### getScrollElement()

View File

@ -1,59 +1,52 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Content - Basic</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script src="/dist/ionic.js"></script>
<link rel="stylesheet" type="text/css" href="/css/ionic.min.css">
</head>
<body>
<ion-app>
<ion-header id="header">
<ion-toolbar style="display: none" id="toolbar2">
<ion-title>Hidden Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Content - Basic</ion-title>
</ion-toolbar>
</ion-header>
<div style="display: flex; flex: 1">
<ion-content padding style="text-align: center; flex: 2" id="content">
<f></f>
<ion-button onclick="toggleFullscreen()">Toggle content.fullscreen</ion-button>
<p>
<ion-button onclick="toggleDisplay('header')" color="secondary">Toggle header</ion-button>
<ion-button onclick="toggleDisplay('footer')" color="secondary">Toggle footer</ion-button>
<ion-button onclick="toggleDisplay('toolbar2')" color="secondary">Toggle 2nd toolbar</ion-button>
</p>
<p>
<ion-button onclick="toggleDisplay('content2')" color="danger">Toggle bottom content</ion-button>
<ion-button onclick="toggleDisplay('content3')" color="danger">Toggle right content</ion-button>
</p>
<p>
<ion-button onclick="myanimation()" color="dark">Animate</ion-button>
</p>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
<ion-content padding style="display: none" id="content3">
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
</div>
<ion-content padding style="display: none" id="content2">
<ion-header id="header">
<ion-toolbar style="display: none" id="toolbar2">
<ion-title>Hidden Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Content - Basic</ion-title>
</ion-toolbar>
</ion-header>
<div style="display: flex; flex: 1">
<ion-content padding style="text-align: center; flex: 2" id="content">
<f></f>
<ion-button onclick="toggleFullscreen()">Toggle content.fullscreen</ion-button>
<p>
<ion-button onclick="toggleDisplay('header')" color="secondary">Toggle header</ion-button>
<ion-button onclick="toggleDisplay('footer')" color="secondary">Toggle footer</ion-button>
<ion-button onclick="toggleDisplay('toolbar2')" color="secondary">Toggle 2nd toolbar</ion-button>
</p>
<p>
<ion-button onclick="toggleDisplay('content2')" color="danger">Toggle bottom content</ion-button>
<ion-button onclick="toggleDisplay('content3')" color="danger">Toggle right content</ion-button>
</p>
<p>
<ion-button onclick="myanimation()" color="dark">Animate</ion-button>
</p>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
<ion-content padding style="display: none" id="content3">
<f></f>
<f></f>
<f></f>
@ -61,12 +54,22 @@
<f></f>
<f></f>
</ion-content>
</div>
<ion-footer id="footer">
<ion-toolbar>
<ion-title>Footer</ion-title>
</ion-toolbar>
</ion-footer>
<ion-content padding style="display: none" id="content2">
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
<ion-footer id="footer">
<ion-toolbar>
<ion-title>Footer</ion-title>
</ion-toolbar>
</ion-footer>
<script>
const content = document.getElementById('content');
@ -104,6 +107,7 @@
#content2 ion-scroll {
background: black;
}
@keyframes ani1 {
0% {
transform: translateX(0)
@ -121,16 +125,19 @@
transform: translateX(0%);
}
}
ion-content.animation {
animation-delay: 500ms;
}
ion-footer.animation {
ion-footer.animation {
animation-delay: 1000ms;
}
.toolbar-background {
background: #f8f8f8b8;
}
f {
display: block;
margin: 15px auto;
@ -142,7 +149,9 @@
f:last-of-type {
background: yellow;
}
</style>
</ion-app>
</body>
</html>

View File

@ -1,59 +1,52 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Content</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script src="/dist/ionic.js"></script>
<link rel="stylesheet" type="text/css" href="/css/ionic.min.css">
</head>
<body>
<ion-app>
<ion-header id="header">
<ion-toolbar style="display: none" id="toolbar2">
<ion-title>Hidden Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Content</ion-title>
</ion-toolbar>
</ion-header>
<div style="display: flex; flex: 1">
<ion-content padding style="text-align: center; flex: 2" id="content">
<f></f>
<ion-button onclick="toggleFullscreen()">Toggle content.fullscreen</ion-button>
<p>
<ion-button onclick="toggleDisplay('header')" color="secondary">Toggle header</ion-button>
<ion-button onclick="toggleDisplay('footer')" color="secondary">Toggle footer</ion-button>
<ion-button onclick="toggleDisplay('toolbar2')" color="secondary">Toggle 2nd toolbar</ion-button>
</p>
<p>
<ion-button onclick="toggleDisplay('content2')" color="danger">Toggle bottom content</ion-button>
<ion-button onclick="toggleDisplay('content3')" color="danger">Toggle right content</ion-button>
</p>
<p>
<ion-button onclick="myanimation()" color="dark">Animate</ion-button>
</p>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
<ion-content padding style="display: none" id="content3">
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
</div>
<ion-content padding style="display: none" id="content2">
<ion-header id="header">
<ion-toolbar style="display: none" id="toolbar2">
<ion-title>Hidden Toolbar</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Content</ion-title>
</ion-toolbar>
</ion-header>
<div style="display: flex; flex: 1">
<ion-content padding style="text-align: center; flex: 2" id="content">
<f></f>
<ion-button onclick="toggleFullscreen()">Toggle content.fullscreen</ion-button>
<p>
<ion-button onclick="toggleDisplay('header')" color="secondary">Toggle header</ion-button>
<ion-button onclick="toggleDisplay('footer')" color="secondary">Toggle footer</ion-button>
<ion-button onclick="toggleDisplay('toolbar2')" color="secondary">Toggle 2nd toolbar</ion-button>
</p>
<p>
<ion-button onclick="toggleDisplay('content2')" color="danger">Toggle bottom content</ion-button>
<ion-button onclick="toggleDisplay('content3')" color="danger">Toggle right content</ion-button>
</p>
<p>
<ion-button onclick="myanimation()" color="dark">Animate</ion-button>
</p>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
<ion-content padding style="display: none" id="content3">
<f></f>
<f></f>
<f></f>
@ -61,12 +54,22 @@
<f></f>
<f></f>
</ion-content>
</div>
<ion-footer id="footer">
<ion-toolbar>
<ion-title>Footer</ion-title>
</ion-toolbar>
</ion-footer>
<ion-content padding style="display: none" id="content2">
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
<ion-footer id="footer">
<ion-toolbar>
<ion-title>Footer</ion-title>
</ion-toolbar>
</ion-footer>
<script>
const content = document.getElementById('content');
@ -104,6 +107,7 @@
#content2 ion-scroll {
background: black;
}
@keyframes ani1 {
0% {
transform: translateX(0)
@ -121,16 +125,19 @@
transform: translateX(0%);
}
}
ion-content.animation {
animation-delay: 500ms;
}
ion-footer.animation {
ion-footer.animation {
animation-delay: 1000ms;
}
.toolbar-background {
background: #f8f8f8b8;
}
f {
display: block;
margin: 15px auto;
@ -142,7 +149,9 @@
f:last-of-type {
background: yellow;
}
</style>
</ion-app>
</body>
</html>

View File

@ -5,6 +5,7 @@
<title>Content - Standalone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script src="/dist/ionic.js"></script>
<link rel="stylesheet" type="text/css" href="/css/ionic.min.css">
</head>
<body>
<ion-content padding>