Skip to content

Commit 11f3a0c

Browse files
authored
Merge pull request #261 from esuau/fix/toggle
fix(toggle): Support checked input
2 parents fe77085 + 3fe57e1 commit 11f3a0c

File tree

6 files changed

+99
-25
lines changed

6 files changed

+99
-25
lines changed

src/checkbox/checkbox.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ export class Checkbox implements ControlValueAccessor, AfterViewInit {
137137
* Reflects whether the checkbox state is indeterminate.
138138
* @readonly
139139
*/
140-
@Input() get indeterminate() {
140+
get indeterminate() {
141141
return this._indeterminate;
142142
}
143143

144144
/**
145145
* Set the checkbox's indeterminate state to match the parameter and transition the view to reflect the change.
146146
*/
147-
set indeterminate(indeterminate: boolean) {
147+
@Input() set indeterminate(indeterminate: boolean) {
148148
let changed = this._indeterminate !== indeterminate;
149149
this._indeterminate = indeterminate;
150150

@@ -161,14 +161,14 @@ export class Checkbox implements ControlValueAccessor, AfterViewInit {
161161
* Returns value `true` if state is selected for the checkbox.
162162
* @readonly
163163
*/
164-
@Input() get checked() {
164+
get checked() {
165165
return this._checked;
166166
}
167167

168168
/**
169169
* Updating the state of a checkbox to match the state of the parameter passed in.
170170
*/
171-
set checked (checked: boolean) {
171+
@Input() set checked (checked: boolean) {
172172
if (checked !== this.checked) {
173173
if (this._indeterminate) {
174174
Promise.resolve().then(() => {

src/switch/switch.component.spec.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
2-
import { ComponentFixture, TestBed, fakeAsync, tick, async } from "@angular/core/testing";
2+
import { ComponentFixture, TestBed } from "@angular/core/testing";
33
import { By } from "@angular/platform-browser";
4-
import { DebugElement } from "@angular/core";
54
import { StaticIconModule } from "../icon/static-icon.module";
65

7-
import { Switch } from "./switch.component";
8-
import { Checkbox } from "../checkbox/checkbox.module";
6+
import { Switch, SwitchChange } from "./switch.component";
97

108
describe("Switch", () => {
119
let component: Switch;
1210
let fixture: ComponentFixture<Switch>;
1311
let labelElement: HTMLElement;
1412
let buttonElement: HTMLElement;
15-
let svgElement: HTMLElement;
1613

1714
beforeEach(() => {
1815
TestBed.configureTestingModule({
@@ -64,4 +61,17 @@ describe("Switch", () => {
6461
expect(labelElement.innerHTML).toContain("bx--toggle__check");
6562
});
6663

64+
it("should match the input checked value", () => {
65+
component.checked = true;
66+
fixture.detectChanges();
67+
expect(buttonElement.attributes.getNamedItem("aria-checked").value).toEqual("true");
68+
});
69+
70+
it("should emit SwitchChange event", (done: any) => {
71+
component.change.subscribe((data: any) => {
72+
expect(data instanceof SwitchChange).toEqual(true);
73+
done();
74+
});
75+
component.emitChangeEvent();
76+
});
6777
});

src/switch/switch.component.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { Checkbox } from "../checkbox/checkbox.component";
22
import {
33
ChangeDetectorRef,
44
Component,
5-
Input
5+
Input,
6+
Output,
7+
EventEmitter
68
} from "@angular/core";
79
import { NG_VALUE_ACCESSOR } from "@angular/forms";
810

@@ -51,14 +53,19 @@ export class SwitchChange {
5153
template: `
5254
<input
5355
class="bx--toggle"
56+
type="checkbox"
5457
[ngClass]="{
5558
'bx--toggle--small': size === 'sm'
5659
}"
5760
[id]="id"
58-
type="checkbox"
59-
(click)="onClick($event)"
61+
[value]="value"
62+
[name]="name"
63+
[required]="required"
64+
[checked]="checked"
6065
[disabled]="disabled"
61-
[attr.aria-checked]="checked">
66+
[attr.aria-checked]="checked"
67+
(change)="onChange($event)"
68+
(click)="onClick($event)">
6269
<label *ngIf="size === 'md'" class="bx--toggle__label" [for]="id">
6370
<span class="bx--toggle__text--left">Off</span>
6471
<span class="bx--toggle__appearance"></span>
@@ -96,6 +103,12 @@ export class Switch extends Checkbox {
96103
*/
97104
id = "switch-" + Switch.switchCount;
98105

106+
/**
107+
* Emits event notifying other classes when a change in state occurs on a switch after a
108+
* click.
109+
*/
110+
@Output() change = new EventEmitter<SwitchChange>();
111+
99112
/**
100113
* Creates an instance of Switch.
101114
*/
@@ -105,4 +118,17 @@ export class Switch extends Checkbox {
105118

106119
console.warn("`ibm-switch` has been deprecated in favour of `ibm-toggle`");
107120
}
121+
122+
/**
123+
* Creates instance of `SwitchChange` used to propagate the change event.
124+
* @memberof To
125+
*/
126+
emitChangeEvent() {
127+
let event = new SwitchChange();
128+
event.source = this;
129+
event.checked = this.checked;
130+
131+
this.propagateChange(this.checked);
132+
this.change.emit(event);
133+
}
108134
}

src/toggle/toggle.component.spec.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
22
import { ComponentFixture, TestBed, fakeAsync, tick, async } from "@angular/core/testing";
33
import { By } from "@angular/platform-browser";
4-
import { DebugElement } from "@angular/core";
54
import { StaticIconModule } from "../icon/static-icon.module";
65

7-
import { Toggle } from "./toggle.component";
8-
import { Checkbox } from "../checkbox/checkbox.module";
6+
import { Toggle, ToggleChange } from "./toggle.component";
97

108
describe("Toggle", () => {
119
let component: Toggle;
1210
let fixture: ComponentFixture<Toggle>;
1311
let labelElement: HTMLElement;
1412
let buttonElement: HTMLElement;
15-
let svgElement: HTMLElement;
1613

1714
beforeEach(() => {
1815
TestBed.configureTestingModule({
@@ -64,4 +61,17 @@ describe("Toggle", () => {
6461
expect(labelElement.innerHTML).toContain("bx--toggle__check");
6562
});
6663

64+
it("should match the input checked value", () => {
65+
component.checked = true;
66+
fixture.detectChanges();
67+
expect(buttonElement.attributes.getNamedItem("aria-checked").value).toEqual("true");
68+
});
69+
70+
it("should emit ToggleChange event", (done: any) => {
71+
component.change.subscribe((data: any) => {
72+
expect(data instanceof ToggleChange).toEqual(true);
73+
done();
74+
});
75+
component.emitChangeEvent();
76+
});
6777
});

src/toggle/toggle.component.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { Checkbox } from "../checkbox/checkbox.component";
22
import {
33
ChangeDetectorRef,
44
Component,
5-
Input
5+
Input,
6+
Output,
7+
EventEmitter
68
} from "@angular/core";
79
import { NG_VALUE_ACCESSOR } from "@angular/forms";
810

@@ -53,14 +55,19 @@ export class ToggleChange {
5355
template: `
5456
<input
5557
class="bx--toggle"
58+
type="checkbox"
5659
[ngClass]="{
5760
'bx--toggle--small': size === 'sm'
5861
}"
5962
[id]="id"
60-
type="checkbox"
61-
(click)="onClick($event)"
63+
[value]="value"
64+
[name]="name"
65+
[required]="required"
66+
[checked]="checked"
6267
[disabled]="disabled"
63-
[attr.aria-checked]="checked">
68+
[attr.aria-checked]="checked"
69+
(change)="onChange($event)"
70+
(click)="onClick($event)">
6471
<label *ngIf="size === 'md'" class="bx--toggle__label" [for]="id">
6572
<span class="bx--toggle__text--left">Off</span>
6673
<span class="bx--toggle__appearance"></span>
@@ -105,6 +112,12 @@ export class Toggle extends Checkbox {
105112
*/
106113
id = "toggle-" + Toggle.toggleCount;
107114

115+
/**
116+
* Emits event notifying other classes when a change in state occurs on a toggle after a
117+
* click.
118+
*/
119+
@Output() change = new EventEmitter<ToggleChange>();
120+
108121
/**
109122
* Creates an instance of Toggle.
110123
* @param {ChangeDetectorRef} changeDetectorRef
@@ -114,4 +127,17 @@ export class Toggle extends Checkbox {
114127
super(changeDetectorRef);
115128
Toggle.toggleCount++;
116129
}
130+
131+
/**
132+
* Creates instance of `ToggleChange` used to propagate the change event.
133+
* @memberof To
134+
*/
135+
emitChangeEvent() {
136+
let event = new ToggleChange();
137+
event.source = this;
138+
event.checked = this.checked;
139+
140+
this.propagateChange(this.checked);
141+
this.change.emit(event);
142+
}
117143
}

src/toggle/toggle.stories.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@ storiesOf("Toggle", module).addDecorator(
1111
.addDecorator(withKnobs)
1212
.add("Basic", () => ({
1313
template: `
14-
<ibm-toggle [disabled]="disabled"></ibm-toggle>
14+
<ibm-toggle [disabled]="disabled" [checked]="checked"></ibm-toggle>
1515
`,
1616
props: {
17-
disabled: boolean("disabled", false)
17+
disabled: boolean("disabled", false),
18+
checked: boolean("checked", false)
1819
}
1920

2021
}))
2122
.add("Small", () => ({
2223
template: `
23-
<ibm-toggle [disabled]="disabled" size="sm"></ibm-toggle>
24+
<ibm-toggle [disabled]="disabled" [checked]="checked" size="sm"></ibm-toggle>
2425
`,
2526
props: {
26-
disabled: boolean("disabled", false)
27+
disabled: boolean("disabled", false),
28+
checked: boolean("checked", false)
2729
}
2830
}));

0 commit comments

Comments
 (0)