fix(colors): override element styling and tweak colors for card and item

* refactor(card): add color/mode classes to header, title, content

- Remove native HTML element styling inside of cards (headings,
paragraph)
- Move the default color for the HTML elements to the content
- Generate colors for the card itself, the header, the content, and the
title using the color input
- Add e2e test for card colors

References #8330

* refactor(item): remove paragraph styles, update activated colors

- Adds test for item colors
- Removes the color from native paragraph elements allowing colors to
be passed

Closes #9081

* refactor(item): bring back paragraph color and override in the item loop

* refactor(card): add back heading and paragraph colors and override in color loop
This commit is contained in:
Brandy Carney
2016-11-10 20:43:22 -05:00
committed by Adam Bradley
parent 898ac3e863
commit ee3decc31d
13 changed files with 535 additions and 18 deletions

View File

@ -102,14 +102,14 @@ $card-ios-header-color: #333 !default;
border: 0; border: 0;
} }
.card-ios ion-card-content { .card-content-ios {
padding: $card-ios-padding-top $card-ios-padding-right $card-ios-padding-bottom $card-ios-padding-left; padding: $card-ios-padding-top $card-ios-padding-right $card-ios-padding-bottom $card-ios-padding-left;
font-size: $card-ios-font-size; font-size: $card-ios-font-size;
line-height: 1.4; line-height: 1.4;
} }
.card-ios ion-card-header { .card-header-ios {
padding: $card-ios-header-padding; padding: $card-ios-header-padding;
font-size: $card-ios-header-font-size; font-size: $card-ios-header-font-size;
@ -117,8 +117,8 @@ $card-ios-header-color: #333 !default;
color: $card-ios-header-color; color: $card-ios-header-color;
} }
.card-ios ion-card-header + ion-card-content, .card-header-ios + .card-content-ios,
.card-ios .item + ion-card-content { .card-ios .item + .card-content-ios {
padding-top: 0; padding-top: 0;
} }
@ -127,7 +127,7 @@ $card-ios-header-color: #333 !default;
font-size: 1.3rem; font-size: 1.3rem;
} }
.card-ios ion-card-title { .card-title-ios {
display: block; display: block;
margin: $card-ios-title-margin; margin: $card-ios-title-margin;
@ -172,3 +172,42 @@ $card-ios-header-color: #333 !default;
.card-ios + ion-card { .card-ios + ion-card {
margin-top: 0; margin-top: 0;
} }
// Generate iOS Card Colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-ios) {
.card-ios .text-ios-#{$color-name} {
color: $color-base;
}
.card-ios-#{$color-name} {
color: $color-contrast;
background-color: $color-base;
.card-header-ios,
.card-title-ios,
.card-content-ios,
p {
color: $color-contrast;
}
@each $color-name, $color-base, $color-contrast in get-colors($colors-ios) {
.text-ios-#{$color-name},
.card-header-ios-#{$color-name},
.card-title-ios-#{$color-name},
.card-content-ios-#{$color-name} {
color: $color-base;
}
}
}
.card-header-ios-#{$color-name},
.card-title-ios-#{$color-name},
.card-content-ios-#{$color-name} {
color: $color-base;
}
}

View File

@ -107,22 +107,22 @@ $card-md-header-color: #222 !default;
border: 0; border: 0;
} }
.card-md ion-card-content { .card-content-md {
padding: $card-md-padding-top $card-md-padding-right $card-md-padding-bottom $card-md-padding-left; padding: $card-md-padding-top $card-md-padding-right $card-md-padding-bottom $card-md-padding-left;
font-size: $card-md-font-size; font-size: $card-md-font-size;
line-height: $card-md-line-height; line-height: $card-md-line-height;
} }
.card-md ion-card-header { .card-header-md {
padding: $card-md-header-padding; padding: $card-md-header-padding;
font-size: $card-md-header-font-size; font-size: $card-md-header-font-size;
color: $card-md-header-color; color: $card-md-header-color;
} }
.card-md ion-card-header + ion-card-content, .card-header-md + .card-content-md,
.card-md .item + ion-card-content { .card-md .item + .card-content-md {
padding-top: 0; padding-top: 0;
} }
@ -131,7 +131,7 @@ $card-md-header-color: #222 !default;
font-size: 1.3rem; font-size: 1.3rem;
} }
.card-md ion-card-title { .card-title-md {
display: block; display: block;
margin: $card-md-title-margin; margin: $card-md-title-margin;
@ -181,3 +181,48 @@ $card-md-header-color: #222 !default;
.card-md + ion-card { .card-md + ion-card {
margin-top: 0; margin-top: 0;
} }
// Generate Material Design Card Colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-md) {
.card-md .text-md-#{$color-name} {
color: $color-base;
}
.card-md-#{$color-name} {
color: $color-contrast;
background-color: $color-base;
.card-header-md,
.card-title-md,
.card-content-md,
h1,
h2,
h3,
h4,
h5,
h6,
p {
color: $color-contrast;
}
@each $color-name, $color-base, $color-contrast in get-colors($colors-md) {
.text-md-#{$color-name},
.card-header-md-#{$color-name},
.card-title-md-#{$color-name},
.card-content-md-#{$color-name} {
color: $color-base;
}
}
}
.card-header-md-#{$color-name},
.card-title-md-#{$color-name},
.card-content-md-#{$color-name} {
color: $color-base;
}
}

View File

@ -43,7 +43,31 @@ export class Card extends Ion {
@Directive({ @Directive({
selector: 'ion-card-content' selector: 'ion-card-content'
}) })
export class CardContent {} export class CardContent extends Ion {
/**
* @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`.
*/
@Input()
set color(val: string) {
this._setColor('card-content', val);
}
/**
* @input {string} The mode to apply to this component.
*/
@Input()
set mode(val: string) {
this._setMode('card-content', val);
}
constructor(config: Config, elementRef: ElementRef, renderer: Renderer) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
}
/** /**
@ -52,7 +76,31 @@ export class CardContent {}
@Directive({ @Directive({
selector: 'ion-card-header' selector: 'ion-card-header'
}) })
export class CardHeader {} export class CardHeader extends Ion {
/**
* @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`.
*/
@Input()
set color(val: string) {
this._setColor('card-header', val);
}
/**
* @input {string} The mode to apply to this component.
*/
@Input()
set mode(val: string) {
this._setMode('card-header', val);
}
constructor(config: Config, elementRef: ElementRef, renderer: Renderer) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
}
/** /**
* @private * @private
@ -60,4 +108,28 @@ export class CardHeader {}
@Directive({ @Directive({
selector: 'ion-card-title' selector: 'ion-card-title'
}) })
export class CardTitle {} export class CardTitle extends Ion {
/**
* @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`.
*/
@Input()
set color(val: string) {
this._setColor('card-title', val);
}
/**
* @input {string} The mode to apply to this component.
*/
@Input()
set mode(val: string) {
this._setMode('card-title', val);
}
constructor(config: Config, elementRef: ElementRef, renderer: Renderer) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
}

View File

@ -108,22 +108,23 @@ $card-wp-header-color: #222 !default;
border: 0; border: 0;
} }
.card-wp ion-card-content { .card-content-wp {
padding: $card-wp-padding-top $card-wp-padding-right $card-wp-padding-bottom $card-wp-padding-left; padding: $card-wp-padding-top $card-wp-padding-right $card-wp-padding-bottom $card-wp-padding-left;
font-size: $card-wp-font-size; font-size: $card-wp-font-size;
line-height: $card-wp-line-height; line-height: $card-wp-line-height;
} }
.card-wp ion-card-header { .card-header-wp {
padding: $card-wp-header-padding; padding: $card-wp-header-padding;
font-size: $card-wp-header-font-size; font-size: $card-wp-header-font-size;
color: $card-wp-header-color; color: $card-wp-header-color;
} }
.card-wp ion-card-header + ion-card-content, .card-header-wp + .card-content-wp,
.card-wp .item + ion-card-content { .card-wp .item + .card-content-wp {
padding-top: 0; padding-top: 0;
} }
@ -132,7 +133,7 @@ $card-wp-header-color: #222 !default;
font-size: 1.3rem; font-size: 1.3rem;
} }
.card-wp ion-card-title { .card-title-wp {
display: block; display: block;
margin: $card-wp-title-margin; margin: $card-wp-title-margin;
@ -182,3 +183,48 @@ $card-wp-header-color: #222 !default;
.card-wp + ion-card { .card-wp + ion-card {
margin-top: 0; margin-top: 0;
} }
// Generate Windows Card Colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-wp) {
.card-wp .text-wp-#{$color-name} {
color: $color-base;
}
.card-wp-#{$color-name} {
color: $color-contrast;
background-color: $color-base;
.card-header-wp,
.card-title-wp,
.card-content-wp,
h1,
h2,
h3,
h4,
h5,
h6,
p {
color: $color-contrast;
}
@each $color-name, $color-base, $color-contrast in get-colors($colors-wp) {
.text-wp-#{$color-name},
.card-header-wp-#{$color-name},
.card-title-wp-#{$color-name},
.card-content-wp-#{$color-name} {
color: $color-base;
}
}
}
.card-header-wp-#{$color-name},
.card-title-wp-#{$color-name},
.card-content-wp-#{$color-name} {
color: $color-base;
}
}

View File

@ -0,0 +1,30 @@
import { Component, NgModule } from '@angular/core';
import { IonicApp, IonicModule } from '../../../..';
@Component({
templateUrl: 'main.html'
})
export class E2EPage {}
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class E2EApp {
rootPage = E2EPage;
}
@NgModule({
declarations: [
E2EApp,
E2EPage
],
imports: [
IonicModule.forRoot(E2EApp)
],
bootstrap: [IonicApp],
entryComponents: [
E2EPage
]
})
export class AppModule {}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,145 @@
<ion-header>
<ion-toolbar>
<ion-title>Card Colors</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="outer-content">
<ion-card>
<ion-card-header color="secondary">
Secondary Header
<span ion-text color="primary">Primary Span in Header</span>
</ion-card-header>
<ion-card-content>
<ion-card-title color="danger">
Danger Title
</ion-card-title>
Some normal text in content.
<h3>Normal h3 in content</h3>
<p>
Normal paragraph in default content.
</p>
<p ion-text color="secondary">
Secondary paragraph in default content.
</p>
</ion-card-content>
<ion-grid>
<ion-row>
<ion-col no-padding>
<button ion-button clear small color="primary">
Primary
</button>
</ion-col>
<ion-col no-padding text-right>
<button ion-button clear small color="danger">
Danger
</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-card>
<ion-card>
<ion-card-header color="primary">
Primary Header
</ion-card-header>
<ion-card-content color="danger">
<ion-card-title color="primary">
Primary Title
</ion-card-title>
Some normal text in danger content.
<h3>Normal h3 in content</h3>
<p>
Normal paragraph in danger content.
</p>
<p ion-text color="primary">
Primary paragraph in danger content.
</p>
</ion-card-content>
<ion-grid>
<ion-row>
<ion-col no-padding>
<button ion-button icon-left clear small color="danger">
<ion-icon name="star"></ion-icon>
Danger
</button>
</ion-col>
<ion-col no-padding text-right>
<button ion-button icon-left clear small color="dark">
<ion-icon name="share"></ion-icon>
Dark
</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-card>
<ion-card color="primary">
<ion-card-header>
Primary Card
</ion-card-header>
<ion-card-content>
<ion-card-title color="danger">
Danger Title
</ion-card-title>
<h3>Heading</h3>
<p>
Normal paragraph in normal content.
</p>
<p ion-text color="secondary">
Secondary paragraph in normal content.
</p>
</ion-card-content>
<ion-grid>
<ion-row>
<ion-col no-padding>
<button ion-button clear small color="light">
Light
</button>
</ion-col>
<ion-col no-padding text-right>
<button ion-button clear small color="danger">
Danger
</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-card>
<ion-card>
<ion-card-header>
Default Header
</ion-card-header>
<ion-card-content>
<ion-card-title>
Default Title
</ion-card-title>
<h3>Heading</h3>
<p>
Normal paragraph in normal content.
</p>
<p ion-text color="primary">
Primary paragraph in normal content.
</p>
</ion-card-content>
</ion-card>
</ion-content>

View File

@ -236,6 +236,14 @@ ion-item-divider.item-ios {
.item-ios-#{$color-name} { .item-ios-#{$color-name} {
color: $color-contrast; color: $color-contrast;
background-color: $color-base; background-color: $color-base;
p {
color: $color-contrast;
}
&.activated {
background-color: color-shade($color-base);
}
} }
} }

View File

@ -239,6 +239,14 @@ ion-item-divider.item-md {
.item-md-#{$color-name} { .item-md-#{$color-name} {
color: $color-contrast; color: $color-contrast;
background-color: $color-base; background-color: $color-base;
p {
color: $color-contrast;
}
&.activated {
background-color: color-shade($color-base);
}
} }
} }

View File

@ -236,6 +236,14 @@ ion-item-divider.item-wp {
.item-wp-#{$color-name} { .item-wp-#{$color-name} {
color: $color-contrast; color: $color-contrast;
background-color: $color-base; background-color: $color-base;
p {
color: $color-contrast;
}
&.activated {
background-color: color-shade($color-base);
}
} }
} }

View File

@ -0,0 +1,33 @@
import { Component, NgModule } from '@angular/core';
import { IonicApp, IonicModule } from '../../../..';
@Component({
templateUrl: 'main.html'
})
export class E2EPage {
}
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class E2EApp {
rootPage = E2EPage;
}
@NgModule({
declarations: [
E2EApp,
E2EPage
],
imports: [
IonicModule.forRoot(E2EApp)
],
bootstrap: [IonicApp],
entryComponents: [
E2EApp,
E2EPage
]
})
export class AppModule {}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,81 @@
<ion-header>
<ion-toolbar>
<ion-title>Item Colors</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-item>
<h1>Heading</h1>
<p>Paragraph</p>
<p color="secondary">Secondary paragraph</p>
</ion-item>
<ion-item color="dark">
<h1>Heading</h1>
<p>Paragraph</p>
</ion-item>
<a ion-item href="#" color="danger">
a[ion-item] danger
</a>
<a ion-item href="#" color="danger" class="activated">
a[ion-item].activated danger
</a>
<button ion-item color="secondary">
button[ion-item]
</button>
<button ion-item color="secondary" class="activated">
button[ion-item].activated secondary
</button>
<ion-item color="primary">
<button ion-button item-left color="dark">Dark</button>
<h1>Heading</h1>
<p>Normal paragraph</p>
<button ion-button outline item-right>Outline</button>
</ion-item>
<button ion-item color="dark">
<button ion-button item-left icon-left>
<ion-icon name="home"></ion-icon>
Left Icon
</button>
left icon buttons
<p color="primary">Primary paragraph</p>
</button>
<button ion-item disabled color="dark">
<button ion-button item-left icon-left>
<ion-icon name="home"></ion-icon>
Left Icon
</button>
disabled left icon buttons
<p color="primary">Primary paragraph</p>
</button>
<ion-item color="light">
<button ion-button item-left icon-right>
Right Icon
<ion-icon name="home"></ion-icon>
</button>
right icon buttons
<button ion-button outline item-right icon-right>
Right Icon
<ion-icon name="star"></ion-icon>
</button>
</ion-item>
<a ion-item disabled color="danger">
a ion-item disabled right icon/text button large
<p>Default paragraph</p>
</a>
</ion-content>