Skip to content

Commit 45536af

Browse files
committed
feat(conent-switcher): add content switcher
1 parent 82456e6 commit 45536af

File tree

6 files changed

+164
-15
lines changed

6 files changed

+164
-15
lines changed

.travis.yml

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
1+
sudo: required
12
dist: trusty
23
language: node_js
3-
sudo: required
44
node_js:
5-
- '8'
5+
- "8"
66
addons:
77
chrome: stable
88
before_install:
9-
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
9+
- "google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &"
1010
before_script:
11-
- export DISPLAY=:99.0
12-
- sh -e /etc/init.d/xvfb start
13-
- sleep 3
14-
- "sudo chown root /opt/google/chrome/chrome-sandbox"
15-
- "sudo chmod 4755 /opt/google/chrome/chrome-sandbox"
16-
script: npm run lint && npm test
17-
sudo: false
11+
- "export DISPLAY=:99.0"
12+
- "sh -e /etc/init.d/xvfb start"
13+
- "sleep 3"
14+
- "sudo chown root /opt/google/chrome/chrome-sandbox"
15+
- "sudo chmod 4755 /opt/google/chrome/chrome-sandbox"
16+
script: "npm run lint && npm test"
1817
deploy:
19-
skip_cleanup: true
20-
provider: script
21-
script: bash ./scripts/deploy.sh
22-
on:
23-
branch: master
18+
-
19+
provider: script
20+
script: "bash ./scripts/deploy.sh"
21+
skip_cleanup: true
22+
true:
23+
branch: master
24+
-
25+
allow-empty-commit: true
26+
27+
github-token: $GH_TOKEN
28+
keep-history: true
29+
local-dir: pages
30+
name: carbon-bot
31+
provider: pages
32+
skip_cleanup: true
33+
true:
34+
branch: master
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {
2+
Directive,
3+
HostBinding,
4+
Input,
5+
HostListener,
6+
Output,
7+
EventEmitter
8+
} from "@angular/core";
9+
10+
@Directive({
11+
selector: "[ibmContentOption]"
12+
})
13+
export class ContentSwitcherOption {
14+
@Input() set active (value: boolean) {
15+
this._active = value;
16+
this.selectedClass = value;
17+
this.ariaSelected = value;
18+
}
19+
20+
get active() {
21+
return this._active;
22+
}
23+
24+
@Input() name = "option";
25+
26+
@Output() selected = new EventEmitter();
27+
28+
@HostBinding("class") switcherClass = "bx--content-switcher-btn";
29+
@HostBinding("class.bx--content-switcher--selected") selectedClass = false;
30+
@HostBinding("attr.role") role = "tab";
31+
@HostBinding("attr.aria-selected") ariaSelected = false;
32+
33+
protected _active = false;
34+
35+
@HostListener("click")
36+
hostClick() {
37+
this.active = true;
38+
this.selected.emit(true);
39+
}
40+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {
2+
Component,
3+
Input,
4+
ContentChildren,
5+
QueryList,
6+
Output,
7+
EventEmitter,
8+
AfterViewInit
9+
} from "@angular/core";
10+
import { ContentSwitcherOption } from "./content-switcher-option.directive";
11+
12+
/**
13+
*
14+
*
15+
*/
16+
@Component({
17+
selector: "ibm-content-switcher",
18+
template: `
19+
<div
20+
[attr.aria-label]="label"
21+
class="bx--content-switcher"
22+
role="tablist">
23+
<ng-content></ng-content>
24+
</div>
25+
`,
26+
})
27+
export class ContentSwitcher implements AfterViewInit {
28+
@Input() label = "content switcher";
29+
30+
@Output() selected = new EventEmitter();
31+
32+
@ContentChildren(ContentSwitcherOption) options: QueryList<ContentSwitcherOption>;
33+
34+
ngAfterViewInit() {
35+
this.options.forEach(option => {
36+
option.selected.subscribe(_ => {
37+
const active = option;
38+
this.options.forEach(option => {
39+
if (option !== active) {
40+
option.active = false;
41+
}
42+
});
43+
this.selected.emit(active);
44+
});
45+
});
46+
}
47+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { NgModule } from "@angular/core";
2+
import { CommonModule } from "@angular/common";
3+
4+
import { ContentSwitcher } from "./content-switcher.component";
5+
import { ContentSwitcherOption } from "./content-switcher-option.directive";
6+
7+
export { ContentSwitcher } from "./content-switcher.component";
8+
export { ContentSwitcherOption } from "./content-switcher-option.directive";
9+
10+
@NgModule({
11+
declarations: [
12+
ContentSwitcher,
13+
ContentSwitcherOption
14+
],
15+
exports: [
16+
ContentSwitcher,
17+
ContentSwitcherOption
18+
],
19+
imports: [CommonModule]
20+
})
21+
export class ContentSwitcherModule { }
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { storiesOf, moduleMetadata } from "@storybook/angular";
2+
import { withNotes } from "@storybook/addon-notes";
3+
import { action } from "@storybook/addon-actions";
4+
import { withKnobs, boolean, object } from "@storybook/addon-knobs/angular";
5+
6+
import { ContentSwitcherModule } from "../";
7+
8+
9+
storiesOf("Content Switcher", module)
10+
.addDecorator(
11+
moduleMetadata({
12+
imports: [
13+
ContentSwitcherModule,
14+
]
15+
})
16+
)
17+
.addDecorator(withKnobs)
18+
.add("Basic", () => ({
19+
template: `
20+
<ibm-content-switcher (selected)="selected($event)">
21+
<button ibmContentOption>First section</button>
22+
<button ibmContentOption>Second section</button>
23+
<button ibmContentOption>Third section</button>
24+
</ibm-content-switcher>
25+
`,
26+
props: {
27+
selected: action("selection changed")
28+
}
29+
}));

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export * from "./table/table.module";
1212
export * from "./tabs/tabs.module";
1313
export * from "./pill-input/pill-input.module";
1414
export * from "./utils/position";
15+
export * from "./content-switcher/content-switcher.module";

0 commit comments

Comments
 (0)