diff --git a/package.json b/package.json
index b3042d6db5..7e14dc124a 100644
--- a/package.json
+++ b/package.json
@@ -56,6 +56,7 @@
"@types/run-sequence": "0.0.28",
"@types/semver": "5.3.30",
"@types/serve-static": "1.7.31",
+ "@types/swiper": "^3.4.2",
"@types/systemjs": "^0.19.33",
"@types/through2": "2.0.29",
"babel-plugin-transform-es2015-modules-systemjs": "6.14.0",
@@ -125,6 +126,7 @@
"serve-static": "1.11.1",
"strip-function": "0.0.3",
"sw-toolbox": "3.4.0",
+ "swiper": "^3.4.2",
"systemjs": "0.19.38",
"through2": "2.0.1",
"ts-node": "1.3.0",
@@ -144,4 +146,4 @@
"pre-push#master": [
"test"
]
-}
\ No newline at end of file
+}
diff --git a/src/components/button/button.ios.scss b/src/components/button/button.ios.scss
index 5b07c8923b..9c0d5ac72b 100644
--- a/src/components/button/button.ios.scss
+++ b/src/components/button/button.ios.scss
@@ -1,4 +1,5 @@
@import "../../themes/ionic.globals.ios";
+@import "./button";
// iOS Button
// --------------------------------------------------
diff --git a/src/components/button/button.md.scss b/src/components/button/button.md.scss
index e7a6f46801..2075666909 100644
--- a/src/components/button/button.md.scss
+++ b/src/components/button/button.md.scss
@@ -1,4 +1,5 @@
@import "../../themes/ionic.globals.md";
+@import "./button";
// Material Design Button
// --------------------------------------------------
diff --git a/src/components/button/button.scss b/src/components/button/button.scss
index b02013b5e2..1ddac2820c 100644
--- a/src/components/button/button.scss
+++ b/src/components/button/button.scss
@@ -9,6 +9,10 @@ $button-round-padding: 0 2.6rem !default;
/// @prop - Border radius of the round button
$button-round-border-radius: 64px !default;
+:host {
+ visibility: inherit !important;
+}
+
.button {
@include appearance(none);
diff --git a/src/components/button/button.ts b/src/components/button/button.ts
index 115919432c..7209436ea6 100644
--- a/src/components/button/button.ts
+++ b/src/components/button/button.ts
@@ -1,9 +1,5 @@
-import { Attribute, ChangeDetectionStrategy, Component, ElementRef, Input, Renderer, ViewEncapsulation } from '@angular/core';
-
-import { Config } from '../../config/config';
-import { Ion } from '../ion';
-import { isTrueProperty } from '../../util/util';
-
+import { Component, h, Ionic, Prop } from '../index';
+type CssClassObject = { [className: string]: boolean };
/**
* @name Button
@@ -64,301 +60,194 @@ import { isTrueProperty } from '../../util/util';
*
* ```
*
- * @advanced
- *
- * ```html
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * ```
- *
- * ```ts
- * @Component({
- * templateUrl: 'main.html'
- * })
- * class E2EPage {
- * isDanger: boolean = true;
- * isSecondary: boolean = false;
- * isRound: boolean = true;
- * isOutline: boolean = false;
- * isClear: boolean = true;
- * myColor: string = 'secondary';
- * myColor2: string = 'dark';
- *
- * logEvent(event) {
- * console.log(event)
- * }
- * }
- *
- * ```
- *
- * @demo /docs/demos/src/button/
- * @see {@link /docs/components#buttons Button Component Docs}
- * @see {@link /docs/components#fabs FabButton Docs}
- * @see {@link ../../fab/FabButton FabButton API Docs}
- * @see {@link ../../fab/FabContainer FabContainer API Docs}
- */
+ */
@Component({
- selector: '[ion-button]',
- template:
- '' +
- '' +
- '' +
- '
',
- changeDetection: ChangeDetectionStrategy.OnPush,
- encapsulation: ViewEncapsulation.None,
+ tag: 'ion-button',
+ styleUrls: {
+ ios: 'button.ios.scss',
+ md: 'button.md.scss',
+ wp: 'button.wp.scss'
+ }
})
-export class Button extends Ion {
- /** @hidden */
- _role: string = 'button'; // bar-button
-
- /** @hidden */
- _size: string; // large/small/default
-
- /** @hidden */
- _style: string = 'default'; // outline/clear/solid
-
- /** @hidden */
- _shape: string; // round/fab
-
- /** @hidden */
- _display: string; // block/full
-
- /** @hidden */
- _decorator: string; // strong
-
- /** @hidden */
- _init: boolean;
+export class Button {
/**
* @input {boolean} If true, activates the large button size.
+ * Type: size
*/
- @Input()
- set large(val: boolean) {
- this._attr('_size', 'large', val);
- }
+ @Prop() large: boolean = false;
/**
* @input {boolean} If true, activates the small button size.
+ * Type: size
*/
- @Input()
- set small(val: boolean) {
- this._attr('_size', 'small', val);
- }
+ @Prop() small: boolean = false;
/**
* @input {boolean} If true, activates the default button size. Normally the default, useful for buttons in an item.
+ * Type: size
*/
- @Input()
- set default(val: boolean) {
- this._attr('_size', 'default', val);
- }
+ @Prop() default: boolean = false;
/**
* @input {boolean} If true, activates a transparent button style with a border.
+ * Type: style
*/
- @Input()
- set outline(val: boolean) {
- this._attr('_style', 'outline', val);
- }
+ @Prop() outline: boolean = false;
/**
* @input {boolean} If true, activates a transparent button style without a border.
+ * Type: style
*/
- @Input()
- set clear(val: boolean) {
- this._attr('_style', 'clear', val);
- }
+ @Prop() clear: boolean = false;
/**
* @input {boolean} If true, activates a solid button style. Normally the default, useful for buttons in a toolbar.
+ * Type: style
*/
- @Input()
- set solid(val: boolean) {
- this._attr('_style', 'solid', val);
- }
+ @Prop() solid: boolean = false;
/**
* @input {boolean} If true, activates a button with rounded corners.
+ * Type: shape
*/
- @Input()
- set round(val: boolean) {
- this._attr('_shape', 'round', val);
- }
+ @Prop() round: boolean = false;
/**
* @input {boolean} If true, activates a button style that fills the available width.
+ * Type: display
*/
- @Input()
- set block(val: boolean) {
- this._attr('_display', 'block', val);
- }
+ @Prop() block: boolean = false;
/**
* @input {boolean} If true, activates a button style that fills the available width without
* a left and right border.
+ * Type: display
*/
- @Input()
- set full(val: boolean) {
- this._attr('_display', 'full', val);
- }
+ @Prop() full: boolean = false;
/**
* @input {boolean} If true, activates a button with a heavier font weight.
+ * Type: decorator
*/
- @Input()
- set strong(val: boolean) {
- this._attr('_decorator', 'strong', val);
- }
+ @Prop() strong: boolean = false;
/**
* @input {string} The mode determines which platform styles to use.
* Possible values are: `"ios"`, `"md"`, or `"wp"`.
* For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
*/
- @Input()
- set mode(val: string) {
- this._assignCss(false);
- this._mode = val;
- this._assignCss(true);
- }
-
- /** @hidden */
- _attr(type: string, attrName: string, attrValue: boolean) {
- if (type === '_style') {
- this._updateColor(this._color, false);
- }
- this._setClass((this)[type], false);
- if (isTrueProperty(attrValue)) {
- (this)[type] = attrName;
- this._setClass(attrName, true);
-
- } else {
- // Special handling for '_style' which defaults to 'default'.
- (this)[type] = (type === '_style' ? 'default' : null);
- this._setClass((this)[type], true);
- }
- if (type === '_style') {
- this._updateColor(this._color, true);
- }
-
- }
+ @Prop() mode: 'ios' | 'md' | 'wp';
/**
* @input {string} The color to use from your Sass `$colors` map.
* Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
* For more information, see [Theming your App](/docs/theming/theming-your-app).
*/
- @Input()
- set color(val: string) {
- this._updateColor(this._color, false);
- this._updateColor(val, true);
- this._color = val;
+ @Prop() color: string;
+ /**
+ * @hidden
+ */
+ getElementClassList(role: string, mode: string): string[] {
+ if (!role) {
+ return [];
+ }
+ return [
+ role,
+ `${role}-${mode}`
+ ];
}
- constructor(
- @Attribute('ion-button') ionButton: string,
- config: Config,
- elementRef: ElementRef,
- renderer: Renderer
- ) {
- super(config, elementRef, renderer);
- this._mode = config.get('mode');
- if (config.get('hoverCSS') === false) {
- this.setElementClass('disable-hover', true);
+ /**
+ * @hidden
+ */
+ getClassList(role: string, type: string, mode: string): string[] {
+ if (!type) {
+ return [];
}
-
- if (ionButton.trim().length > 0) {
- this.setRole(ionButton);
- }
- }
-
- /** @hidden */
- ngAfterContentInit() {
- this._init = true;
- this._assignCss(true);
+ type = type.toLocaleLowerCase();
+ return [
+ `${role}-${type}`,
+ `${role}-${type}-${mode}`
+ ];
}
/**
* @hidden
*/
- setRole(val: string) {
- this._assignCss(false);
- this._role = val;
- this._assignCss(true);
+ getColorClassList(color: string, role: string, style: string, mode: string): string | null {
+ if (!color) {
+ return null;
+ }
+ style = (role !== 'bar-button' && style === 'solid') ? 'default' : style;
+ let className =
+ role +
+ ((style && style !== 'default') ?
+ '-' + style.toLowerCase() :
+ '');
+
+ console.log(role, style, className, mode, color);
+
+ return `${className}-${mode}-${color}`;
}
- /**
- * @hidden
- */
- _assignCss(assignCssClass: boolean) {
- let role = this._role;
- if (role) {
- this.setElementClass(role, assignCssClass); // button
- this.setElementClass(`${role}-${this._mode}`, assignCssClass); // button
+ render() {
+ var role = 'button';
+ var size =
+ (this.large ? 'large' : null) ||
+ (this.small ? 'small' : null) ||
+ (this.default ? 'default' : null);
- this._setClass(this._style, assignCssClass); // button-clear
- this._setClass(this._shape, assignCssClass); // button-round
- this._setClass(this._display, assignCssClass); // button-full
- this._setClass(this._size, assignCssClass); // button-small
- this._setClass(this._decorator, assignCssClass); // button-strong
- this._updateColor(this._color, assignCssClass); // button-secondary, bar-button-secondary
- }
- }
+ var style =
+ (this.outline ? 'outline' : null) ||
+ (this.clear ? 'clear' : null) ||
+ (this.solid ? 'solid' : null) ||
+ 'default';
- /**
- * @hidden
- */
- _setClass(type: string, assignCssClass: boolean) {
- if (type && this._init) {
- type = type.toLocaleLowerCase();
- this.setElementClass(`${this._role}-${type}`, assignCssClass);
- this.setElementClass(`${this._role}-${type}-${this._mode}`, assignCssClass);
- }
- }
+ var shape = (this.round ? 'round' : null);
- /**
- * @hidden
- */
- _updateColor(color: string, isAdd: boolean) {
- if (color && this._init) {
- // The class should begin with the button role
- // button, bar-button
- let className = this._role;
+ var display =
+ (this.block ? 'block' : null) ||
+ (this.full ? 'full' : null);
- // If the role is not a bar-button, don't apply the solid style
- let style = this._style;
- style = (this._role !== 'bar-button' && style === 'solid' ? 'default' : style);
+ var decorator = (this.strong ? 'strong' : null);
- className += (style !== null && style !== '' && style !== 'default' ? '-' + style.toLowerCase() : '');
+ var buttonClasses: CssClassObject = []
+ .concat(
+ this.getElementClassList(role, this.mode),
+ this.getClassList(role, shape, this.mode),
+ this.getClassList(role, display, this.mode),
+ this.getClassList(role, size, this.mode),
+ this.getClassList(role, decorator, this.mode),
+ this.getColorClassList(this.color, role, style, this.mode)
+ )
+ .reduce((prevValue, cssClass) => {
+ prevValue[cssClass] = true;
+ return prevValue;
+ }, {});
- if (color !== null && color !== '') {
- this.setElementClass(`${className}-${this._mode}-${color}`, isAdd);
- }
- }
+ return h(this,
+ h('div', {
+ class: buttonClasses
+ },
+ [
+ h('span', {
+ class: {
+ 'button-inner': true
+ }
+ },
+ h('slot')
+ ),
+ h('div', {
+ class: {
+ 'button-effect': true
+ }
+ }
+ )
+ ]
+ )
+ );
}
}
diff --git a/src/components/button/button.wp.scss b/src/components/button/button.wp.scss
index 5d6892bf0b..cf6d76e8b9 100644
--- a/src/components/button/button.wp.scss
+++ b/src/components/button/button.wp.scss
@@ -1,4 +1,5 @@
@import "../../themes/ionic.globals.wp";
+@import "./button";
// Windows Button
// --------------------------------------------------
diff --git a/src/components/button/test/button.spec.ts b/src/components/button/test/button.spec.ts
deleted file mode 100644
index 0a5d6d5471..0000000000
--- a/src/components/button/test/button.spec.ts
+++ /dev/null
@@ -1,264 +0,0 @@
-import { Button } from '../button';
-import { Config } from '../../../config/config';
-import { mockConfig, mockElementRef, mockRenderer } from '../../../util/mock-providers';
-
-
-describe('button', () => {
-
- it('should set a different button role', () => {
- let b = mockButton();
- b.outline = true;
- b.small = true;
- b.full = true;
- b.color = 'primary';
- b.setRole('bar-button');
- b._assignCss(true);
-
- expect(hasClass(b, 'bar-button-outline')).toEqual(true);
- expect(hasClass(b, 'bar-button-small')).toEqual(true);
- expect(hasClass(b, 'bar-button-full')).toEqual(true);
- expect(hasClass(b, 'bar-button-outline-ios-primary')).toEqual(true);
-
- expect(hasClass(b, 'button-outline')).toEqual(false);
- expect(hasClass(b, 'button-small')).toEqual(false);
- expect(hasClass(b, 'button-full')).toEqual(false);
- expect(hasClass(b, 'button-primary')).toEqual(false);
- });
-
- it('should remove button color attributes and add different role', () => {
- let b = mockButton();
- b.outline = true;
- b.small = true;
- b.full = true;
- b.color = 'primary';
-
- b._assignCss(true);
- expect(hasClass(b, 'button-outline')).toEqual(true);
- expect(hasClass(b, 'button-small')).toEqual(true);
- expect(hasClass(b, 'button-full')).toEqual(true);
- expect(hasClass(b, 'button-outline-ios-primary')).toEqual(true);
-
- b._assignCss(false);
- expect(hasClass(b, 'button-outline')).toEqual(false);
- expect(hasClass(b, 'button-small')).toEqual(false);
- expect(hasClass(b, 'button-full')).toEqual(false);
- expect(hasClass(b, 'button-outline-ios-primary')).toEqual(false);
- });
-
- it('should read button color attributes with styles', () => {
- let b = mockButton();
- b.outline = true;
- b.small = true;
- b.full = true;
- b.color = 'primary';
-
- b._assignCss(true);
- expect(hasClass(b, 'button')).toEqual(true);
- expect(hasClass(b, 'button-outline')).toEqual(true);
- expect(hasClass(b, 'button-small')).toEqual(true);
- expect(hasClass(b, 'button-full')).toEqual(true);
- expect(hasClass(b, 'button-outline-ios-primary')).toEqual(true);
-
- b = mockButton();
- b.clear = true;
- b.color = 'primary';
- b.color = 'secondary';
-
- b._assignCss(true);
- expect(hasClass(b, 'button')).toEqual(true);
- expect(hasClass(b, 'button-clear')).toEqual(true);
- expect(hasClass(b, 'button-clear-ios-primary')).toEqual(false);
- expect(hasClass(b, 'button-clear-ios-secondary')).toEqual(true);
-
- b = mockButton();
- b.solid = true;
- b.color = 'primary';
- b.color = 'secondary';
-
- b._assignCss(true);
- expect(hasClass(b, 'button')).toEqual(true);
- expect(hasClass(b, 'button-solid')).toEqual(true);
- expect(hasClass(b, 'button-ios-primary')).toEqual(false);
- expect(hasClass(b, 'button-ios-secondary')).toEqual(true);
-
- b = mockButton();
- b.solid = true;
- b.color = 'primary';
- b.color = 'secondary';
-
- b.setRole('bar-button');
- b._assignCss(true);
- expect(hasClass(b, 'bar-button-solid')).toEqual(true);
- expect(hasClass(b, 'bar-button-solid-ios-primary')).toEqual(false);
- expect(hasClass(b, 'bar-button-solid-ios-secondary')).toEqual(true);
- });
-
- it('should auto add the default style', () => {
- let b = mockButton();
- b._assignCss(true);
- expect(hasClass(b, 'button')).toEqual(true);
- expect(hasClass(b, 'button-default')).toEqual(true);
-
- b = mockButton();
- b.clear = true;
-
- b._assignCss(true);
- expect(hasClass(b, 'button')).toEqual(true);
- expect(hasClass(b, 'button-default')).toEqual(false);
- expect(hasClass(b, 'button-clear')).toEqual(true);
- });
-
- it('should read button color attributes', () => {
- let b = mockButton();
- b.color = 'primary';
- b._assignCss(true);
- expect(hasClass(b, 'button-ios-primary')).toEqual(true);
-
- b = mockButton();
- b.color = 'primary';
- b.color = 'secondary';
- b._assignCss(true);
- expect(hasClass(b, 'button-ios-primary')).toEqual(false);
- expect(hasClass(b, 'button-ios-secondary')).toEqual(true);
- });
-
- it('should read button style attributes', () => {
- let b = mockButton();
- b.clear = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-clear')).toEqual(true);
-
- b = mockButton();
- b.outline = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-outline')).toEqual(true);
-
- b = mockButton();
- b.solid = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-solid')).toEqual(true);
-
- b = mockButton();
- b.clear = true;
- b.outline = true;
- b.small = true;
- b.full = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-clear')).toEqual(false);
- expect(hasClass(b, 'button-outline')).toEqual(true);
- expect(hasClass(b, 'button-small')).toEqual(true);
- expect(hasClass(b, 'button-full')).toEqual(true);
-
- b = mockButton();
- b.outline = true;
- b.setRole('bar-button');
- b._assignCss(true);
- expect(hasClass(b, 'bar-button-outline')).toEqual(true);
- });
-
- it('should read button shape attributes', () => {
- let b = mockButton();
- b.round = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-round')).toEqual(true);
- });
-
- it('should read button display attributes', () => {
- let b = mockButton();
- b.block = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-block')).toEqual(true);
-
- b = mockButton();
- b.full = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-full')).toEqual(true);
-
- b = mockButton();
- b.block = true;
- b.full = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-block')).toEqual(false);
- expect(hasClass(b, 'button-full')).toEqual(true);
- });
-
- it('should read button size attributes', () => {
- let b = mockButton();
- b.small = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-small')).toEqual(true);
-
- b = mockButton();
- b.large = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-large')).toEqual(true);
-
- b = mockButton();
- b.large = true;
- b.small = true;
- b._assignCss(true);
- expect(hasClass(b, 'button-large')).toEqual(false);
- expect(hasClass(b, 'button-small')).toEqual(true);
- });
-
- it('should add button css class', () => {
- let b = mockButton();
- b._assignCss(true);
- expect(hasClass(b, 'button')).toEqual(true);
- });
-
- it('should add disable-hover css class', () => {
- let config = mockConfig({
- hoverCSS: false
- });
- let b = mockButton(config);
-
- expect(hasClass(b, 'disable-hover')).toEqual(true);
- });
-
- it('should set defaults', () => {
- let b = mockButton();
- expect(b._role).toEqual('button');
- expect(b._size).toEqual(undefined);
- expect(b._color).toEqual(undefined);
- expect(b._style).toEqual('default');
- expect(b._display).toEqual(undefined);
- });
-
- it('should set different modes', () => {
- let b = mockButton();
-
- b._assignCss(true);
- expect(b._mode).toEqual('ios');
- expect(hasClass(b, 'button')).toEqual(true);
- expect(hasClass(b, 'button-ios')).toEqual(true);
-
- b.mode = 'wp';
- expect(b._mode).toEqual('wp');
- expect(hasClass(b, 'button-wp')).toEqual(true);
-
- b.mode = 'blah';
- expect(b._mode).toEqual('blah');
- expect(hasClass(b, 'button-blah')).toEqual(true);
- });
-
- it('should add alert-button css class', () => {
- let b = mockButton(null, 'alert-button');
- b._assignCss(true);
- expect(hasClass(b, 'alert-button')).toEqual(true);
- });
-
-});
-
-function mockButton(config?: Config, ionButton?: string) {
- config = config || mockConfig();
- ionButton = ionButton || '';
- let b = new Button(ionButton, config, mockElementRef(), mockRenderer());
- b._init = true;
- b.mode = 'ios';
- return b;
-}
-
-function hasClass(button: any, className: string) {
- return button._elementRef.nativeElement.classList.contains(className);
-}
diff --git a/src/components/item/item.ts b/src/components/item/item.ts
index 021c99610f..e8a16fd805 100644
--- a/src/components/item/item.ts
+++ b/src/components/item/item.ts
@@ -414,11 +414,11 @@ export class Item extends Ion {
*/
@ContentChildren(Button)
set _buttons(buttons: QueryList