refactor(components): move function to get classes from host to utils

Moved getElementClassObject function to utils/theme and updated the
components with child buttons to use this function to get the host
classes.

Adds the ability to pass classes down from host to child for content
and segment button

closes ionic-team/stencil#84
This commit is contained in:
Brandy Carney
2017-08-11 13:26:10 -04:00
parent 319d38ac1a
commit 4dcb174245
11 changed files with 80 additions and 68 deletions

View File

@ -1,5 +1,7 @@
import { Component, Element, Prop, CssClassMap } from '@stencil/core';
import { getElementClassObject } from '../../utils/theme';
/**
* @name Button
* @module ionic
@ -178,7 +180,9 @@ export class Button {
const decorator = (this.strong ? 'strong' : null);
const buttonClasses: CssClassMap = []
const hostClasses = getElementClassObject(this.el.classList);
const elementClasses: CssClassMap = []
.concat(
getButtonClassList(buttonType, mode),
getClassList(buttonType, shape, mode),
@ -186,8 +190,7 @@ export class Button {
getClassList(buttonType, size, mode),
getClassList(buttonType, decorator, mode),
getStyleClassList(mode, this.color, buttonType, this.outline, this.clear, this.solid),
getItemClassList(this.itemButton, size),
getElementClassList(this.el.classList)
getItemClassList(this.itemButton, size)
)
.reduce((prevValue, cssClass) => {
prevValue[cssClass] = true;
@ -196,6 +199,11 @@ export class Button {
const TagType = this.href ? 'a' : 'button';
const buttonClasses = {
...hostClasses,
...elementClasses
}
return (
<TagType class={buttonClasses} disabled={this.disabled}>
<span class='button-inner'>
@ -292,14 +300,3 @@ function getStyleClassList(mode: string, color: string, buttonType: string, outl
function getItemClassList(itemButton: boolean, size: string) {
return itemButton && !size ? ['item-button'] : [];
}
/**
* Get the element classes to add to the child element
*/
function getElementClassList(elmClassList: DOMTokenList) {
const classList: string[] = [];
for (var i = 0; i < elmClassList.length; i++) {
classList.push(elmClassList.item(i));
}
return classList;
}

View File

@ -1,5 +1,6 @@
import { Component, CssClassMap, Element, Prop } from '@stencil/core';
import { getElementClassObject } from '../../utils/theme';
@Component({
tag: 'ion-chip-button',
@ -71,25 +72,14 @@ export class ChipButton {
return classList;
}
/**
* @hidden
* Get the element classes to add to the child element
*/
private getElementClassList() {
let classList = [].concat(
this.el.className.length ? this.el.className.split(' ') : []
);
return classList;
}
render() {
const buttonType = 'chip-button';
var buttonClasses: CssClassMap = []
const hostClasses = getElementClassObject(this.el.classList);
const elementClasses: CssClassMap = []
.concat(
this.getButtonClassList(buttonType, this.mode),
this.getElementClassList(),
this.getStyleClassList(buttonType)
)
.reduce((prevValue, cssClass) => {
@ -99,6 +89,11 @@ export class ChipButton {
const TagType = this.href ? 'a' : 'button';
const buttonClasses = {
...hostClasses,
...elementClasses
}
return (
<TagType class={buttonClasses} disabled={this.disabled}>
<span class='button-inner'>

View File

@ -76,7 +76,7 @@
<ion-chip id="chip1">
<ion-label>Default</ion-label>
<ion-chip-button clear onclick="del('chip1')">
<ion-chip-button clear onclick="del('chip1')" class="my-custom-chip">
<ion-icon name="close-circle"></ion-icon>
</ion-chip-button>
</ion-chip>

View File

@ -1,6 +1,6 @@
import { Component, Element, Prop } from '@stencil/core';
import { Config, Scroll, ScrollDetail } from '../../index';
import { createThemedClasses } from '../../utils/theme';
import { createThemedClasses, getElementClassObject } from '../../utils/theme';
import { getParentElement, getToolbarHeight } from '../../utils/helpers';
@ -103,11 +103,18 @@ export class Content {
if (this.ionScrollEnd) {
props['ionScrollEnd'] = this.ionScrollEnd.bind(this);
}
const themedClasses = createThemedClasses(this.mode, this.color, 'content');
themedClasses['statusbar-padding'] = this.config.getBoolean('statusbarPadding');
const hostClasses = getElementClassObject(this.el.classList);
const scrollClasses = {
...themedClasses,
...hostClasses,
'statusbar-padding': this.config.getBoolean('statusbarPadding')
}
return (
<ion-scroll style={scrollStyle} props={props} class={themedClasses}>
<ion-scroll style={scrollStyle} props={props} class={scrollClasses}>
<slot></slot>
</ion-scroll>
);

View File

@ -1,5 +1,5 @@
import { Component, Element, CssClassMap, Method, Prop, State } from '@stencil/core';
import { createThemedClasses } from '../../utils/theme';
import { createThemedClasses, getElementClassObject } from '../../utils/theme';
/**
@ -110,18 +110,6 @@ export class FabButton {
this.setActiveLists(false);
}
/**
* @hidden
* Get the element classes to add to the child element
*/
getElementClassList() {
let classList = [].concat(
this.el.className.length ? this.el.className.split(' ') : []
);
return classList;
}
/**
* @hidden
* Get the classes for fab buttons in lists
@ -164,10 +152,10 @@ export class FabButton {
render() {
const themedClasses = createThemedClasses(this.mode, this.color, 'fab');
const hostClasses = getElementClassObject(this.el.classList);
var fabClasses: CssClassMap = []
const elementClasses: CssClassMap = []
.concat(
this.getElementClassList(),
this.getFabListClassList(),
this.getFabActiveClassList(),
this.getFabShowClassList()
@ -179,7 +167,11 @@ export class FabButton {
const TagType = this.href ? 'a' : 'button';
fabClasses = Object.assign(fabClasses, themedClasses);
const fabClasses = {
...themedClasses,
...hostClasses,
...elementClasses
}
return (
<TagType class={fabClasses} onClick={this.clickedFab.bind(this)} disabled={this.disabled}>

View File

@ -1,7 +1,7 @@
import { Component, Event, EventEmitter, Prop, State } from '@stencil/core';
import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core';
import { CssClassMap } from '../../index';
import { createThemedClasses } from '../../utils/theme';
import { createThemedClasses, getElementClassObject } from '../../utils/theme';
/**
@ -49,6 +49,8 @@ export class SegmentButton {
mode: string;
color: string;
@Element() el: HTMLElement;
@Event() ionClick: EventEmitter;
@State() activated: boolean = false;
@ -92,7 +94,7 @@ export class SegmentButton {
/**
* @hidden
* Get the element classes to add to the child element
* Get the classes for the segment button state
*/
getElementClassList() {
let classList = [].concat(
@ -104,9 +106,10 @@ export class SegmentButton {
}
render() {
const segmentButtonCss = createThemedClasses(this.mode, this.color, 'segment-button');
const themedClasses = createThemedClasses(this.mode, this.color, 'segment-button');
const hostClasses = getElementClassObject(this.el.classList);
var segmentButtonClasses: CssClassMap = []
const elementClasses: CssClassMap = []
.concat(
this.getElementClassList()
)
@ -115,10 +118,14 @@ export class SegmentButton {
return prevValue;
}, {});
segmentButtonClasses = Object.assign(segmentButtonClasses, segmentButtonCss);
const buttonClasses = {
...themedClasses,
...hostClasses,
...elementClasses
};
return [
<button onClick={this.segmentButtonClick.bind(this)} class={segmentButtonClasses} aria-pressed={this.activated}>
<button onClick={this.segmentButtonClick.bind(this)} class={buttonClasses} aria-pressed={this.activated}>
<slot></slot>
</button>
];

View File

@ -37,11 +37,11 @@ export class Spinner {
}
hostData() {
const spinnerThemedClasses = createThemedClasses(this.mode, this.color, `spinner spinner-${this.name}`);
spinnerThemedClasses['spinner-paused'] = true;
const themedClasses = createThemedClasses(this.mode, this.color, `spinner spinner-${this.name}`);
themedClasses['spinner-paused'] = true;
return {
class: spinnerThemedClasses
class: themedClasses
};
}

View File

@ -7,6 +7,6 @@
<script src="/dist/ionic.js"></script>
</head>
<body>
<ion-spinner></ion-spinner>
<ion-spinner name="bubbles"></ion-spinner>
</body>
</html>

View File

@ -53,10 +53,10 @@ export class ToolbarTitle {
color: string;
render() {
const titleClasses = createThemedClasses(this.mode, this.color, 'toolbar-title');
const themedClasses = createThemedClasses(this.mode, this.color, 'toolbar-title');
return [
<div class={titleClasses}>
<div class={themedClasses}>
<slot></slot>
</div>
];

View File

@ -1,4 +1,3 @@
export function isDef(v: any): boolean { return v !== undefined && v !== null; }
export function isUndef(v: any): boolean { return v === undefined || v === null; }
@ -152,4 +151,4 @@ export function swipeShouldReset(isResetDirection: boolean, isMovingFast: boolea
// The resulting expression was generated by resolving the K-map (Karnaugh map):
let shouldClose = (!isMovingFast && isOnResetZone) || (isResetDirection && isMovingFast);
return shouldClose;
}
}

View File

@ -1,10 +1,12 @@
import { CssClassMap } from '@stencil/core';
/**
* Create the mode and color classes for the component based on the classes passed in
*/
export function createThemedClasses(mode: string, color: string, classes: string): CssClassMap {
let classObj: CssClassMap = {};
export function createThemedClasses(mode: string, color: string, classList: string): CssClassMap {
let allClassObj: CssClassMap = {};
return classList.split(' ')
return classes.split(' ')
.reduce((classObj: CssClassMap, classString: string): CssClassMap => {
classObj[classString] = true;
@ -18,5 +20,18 @@ export function createThemedClasses(mode: string, color: string, classList: stri
}
return classObj;
}, allClassObj);
}, classObj);
}
/**
* Get the classes from a class list and return them as an object
*/
export function getElementClassObject(classList: DOMTokenList): CssClassMap {
let classObj: CssClassMap = {};
for (var i = 0; i < classList.length; i++) {
classObj[classList.item(i)] = true;
}
return classObj;
}