Skip to content

Commit 154a69c

Browse files
committed
feat(buttons): dynamically add button attributes
Closes #5186
1 parent 7b14a29 commit 154a69c

File tree

8 files changed

+132
-26
lines changed

8 files changed

+132
-26
lines changed

ionic/components/button/button.ts

Lines changed: 94 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {Component, ElementRef, Renderer, Attribute, Optional, Input} from 'angul
22

33
import {Config} from '../../config/config';
44
import {Toolbar} from '../toolbar/toolbar';
5+
import {isTrueProperty} from '../../util/util';
56

67

78
/**
@@ -45,20 +46,108 @@ export class Button {
4546
private _style: string = 'default'; // outline/clear/solid
4647
private _shape: string = null; // round/fab
4748
private _display: string = null; // block/full
48-
private _lastColor: string = null;
4949
private _colors: Array<string> = []; // primary/secondary
5050
private _icon: string = null; // left/right/only
5151
private _disabled: boolean = false; // disabled
52+
private _init: boolean;
5253

5354
/**
5455
* @private
5556
*/
5657
isItem: boolean;
5758

5859
/**
59-
* @private
60+
* @input {string} Large button.
61+
*/
62+
@Input()
63+
set large(val: boolean) {
64+
this._attr('_size', 'large', val);
65+
}
66+
67+
/**
68+
* @input {string} Small button.
69+
*/
70+
@Input()
71+
set small(val: boolean) {
72+
this._attr('_size', 'small', val);
73+
}
74+
75+
/**
76+
* @input {string} Default button.
77+
*/
78+
@Input()
79+
set default(val: boolean) {
80+
this._attr('_size', 'default', val);
81+
}
82+
83+
/**
84+
* @input {string} A transparent button with a border.
85+
*/
86+
@Input()
87+
set outline(val: boolean) {
88+
this._attr('_style', 'outline', val);
89+
}
90+
91+
/**
92+
* @input {string} A transparent button without a border.
93+
*/
94+
@Input()
95+
set clear(val: boolean) {
96+
this._attr('_style', 'clear', val);
97+
}
98+
99+
/**
100+
* @input {string} Force a solid button. Useful for buttons within an item.
101+
*/
102+
@Input()
103+
set solid(val: boolean) {
104+
this._attr('_style', 'solid', val);
105+
}
106+
107+
/**
108+
* @input {string} A button with rounded corners.
60109
*/
61-
@Input() color: string;
110+
@Input()
111+
set round(val: boolean) {
112+
this._attr('_shape', 'round', val);
113+
}
114+
115+
/**
116+
* @input {string} A button that fills its parent container with a border-radius.
117+
*/
118+
@Input()
119+
set block(val: boolean) {
120+
this._attr('_display', 'block', val);
121+
}
122+
123+
/**
124+
* @input {string} A button that fills its parent container without a border-radius or borders on the left/right.
125+
*/
126+
@Input()
127+
set full(val: boolean) {
128+
this._attr('_display', 'full', val);
129+
}
130+
131+
_attr(type: string, attrName: string, attrValue: boolean) {
132+
this._setClass(this[type], false);
133+
if (isTrueProperty(attrValue)) {
134+
this[type] = attrName;
135+
this._setClass(attrName, true);
136+
137+
} else {
138+
this[type] = null;
139+
}
140+
}
141+
142+
/**
143+
* @input {string} Dynamically set which color attribute this button should use.
144+
*/
145+
@Input()
146+
set color(val: string) {
147+
this._assignCss(false);
148+
this._colors = [val];
149+
this._assignCss(true);
150+
}
62151

63152
constructor(
64153
config: Config,
@@ -92,26 +181,11 @@ export class Button {
92181
* @private
93182
*/
94183
ngAfterContentInit() {
95-
this._lastColor = this.color;
96-
if (this.color) {
97-
this._colors = [this.color];
98-
}
184+
this._init = true;
99185
this._readIcon(this._elementRef.nativeElement);
100186
this._assignCss(true);
101187
}
102188

103-
/**
104-
* @private
105-
*/
106-
ngAfterContentChecked() {
107-
if (this._lastColor !== this.color) {
108-
this._assignCss(false);
109-
this._lastColor = this.color;
110-
this._colors = [this.color];
111-
this._assignCss(true);
112-
}
113-
}
114-
115189
/**
116190
* @private
117191
*/
@@ -225,7 +299,7 @@ export class Button {
225299
* @private
226300
*/
227301
private _setClass(type: string, assignCssClass: boolean) {
228-
if (type) {
302+
if (type && this._init) {
229303
this._renderer.setElementClass(this._elementRef.nativeElement, this._role + '-' + type, assignCssClass);
230304
}
231305
}

ionic/components/button/test/block/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ import {App} from 'ionic-angular';
44
@App({
55
templateUrl: 'main.html'
66
})
7-
class E2EApp {}
7+
class E2EApp {
8+
blockButton = true;
9+
10+
toggleBlock() {
11+
this.blockButton = !this.blockButton;
12+
}
13+
}

ionic/components/button/test/block/main.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@
3535
<button block round outline>button[block][round][outline]</button>
3636
</p>
3737

38+
<p>
39+
<button [block]="blockButton" (click)="toggleBlock()">Toggle Block</button>
40+
</p>
41+
3842
</ion-content>

ionic/components/button/test/button.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export function run() {
179179

180180
});
181181

182-
function mockButton(attrs, config) {
182+
function mockButton(attrs?, config?) {
183183
config = config || new Config();
184184
let elementRef = {
185185
nativeElement: document.createElement('button')
@@ -189,12 +189,14 @@ export function run() {
189189
elementRef.nativeElement.setAttribute(attrs[i], '');
190190
}
191191
}
192-
let renderer = {
192+
let renderer: any = {
193193
setElementClass: function(nativeElement, className, shouldAdd) {
194194
nativeElement.classList[shouldAdd ? 'add' : 'remove'](className);
195195
}
196196
};
197-
return new Button(config, elementRef, renderer, null);
197+
let b = new Button(config, elementRef, renderer, null);
198+
b._init = true;
199+
return b;
198200
}
199201

200202
function hasClass(button, className) {

ionic/components/button/test/clear/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ import {App} from 'ionic-angular';
44
@App({
55
templateUrl: 'main.html'
66
})
7-
class E2EApp {}
7+
class E2EApp {
8+
clearButton = true;
9+
10+
toggleClear() {
11+
this.clearButton = !this.clearButton;
12+
}
13+
}

ionic/components/button/test/clear/main.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@
3535
<button clear dark class="activated">Dark.activated</button>
3636
</p>
3737

38+
<p>
39+
<button [clear]="clearButton" (click)="toggleClear()">Toggle Clear</button>
40+
</p>
41+
3842
</ion-content>

ionic/components/button/test/outline/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ import {App} from 'ionic-angular';
44
@App({
55
templateUrl: 'main.html'
66
})
7-
class E2EApp {}
7+
class E2EApp {
8+
outlineButton = true;
9+
10+
toggleOutline() {
11+
this.outlineButton = !this.outlineButton;
12+
}
13+
}

ionic/components/button/test/outline/main.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,8 @@
5151
<button outline block secondary class="activated">[outline][block][secondary].activated</button>
5252
</p>
5353

54+
<p>
55+
<button [outline]="outlineButton" (click)="toggleOutline()">Toggle Outline</button>
56+
</p>
57+
5458
</ion-content>

0 commit comments

Comments
 (0)