Skip to content

Commit e13d405

Browse files
committed
Merge branch 'tooltip-icon' of https://github.com/youda97/carbon-components-angular into tooltip-icon
2 parents 26a909b + e971374 commit e13d405

10 files changed

+339
-24
lines changed

src/i18n/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@
131131
"BUTTON_ARIA_LEFT": "Go to the previous tab",
132132
"BUTTON_ARIA_RIGHT": "Go to the next tab"
133133
},
134+
"TILES": {
135+
"TILE": "tile",
136+
"EXPAND": "Expand",
137+
"COLLAPSE": "Collapse"
138+
},
134139
"TOGGLE": {
135140
"OFF": "Off",
136141
"ON": "On"

src/notification/notification-content.interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export interface NotificationContent {
55
duration?: number;
66
smart?: boolean;
77
closeLabel?: any;
8-
message: string;
8+
message?: string;
99
}
1010

1111
export interface ToastContent extends NotificationContent {

src/notification/notification.component.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ import { of } from "rxjs";
1515

1616
/**
1717
* Notification messages are displayed toward the top of the UI and do not interrupt user’s work.
18-
*
19-
* @export
20-
* @class Notification
2118
*/
2219
@Component({
2320
selector: "ibm-notification",
@@ -65,10 +62,9 @@ export class Notification {
6562
/**
6663
* Can have `type`, `title`, and `message` members.
6764
*
68-
* `type` can be one of `"info"`, `"warning"`, `"danger"`, `"success"`
69-
*
70-
* `message` is message for notification to display
65+
* `type` can be one of `"info"`, `"warning"`, `"error"`, `"success"`
7166
*
67+
* `message` is the message to display
7268
*/
7369
@Input() get notificationObj(): NotificationContent {
7470
return this._notificationObj;
@@ -82,9 +78,6 @@ export class Notification {
8278

8379
/**
8480
* Emits on close.
85-
*
86-
* @type {EventEmitter<any>}
87-
* @memberof Notification
8881
*/
8982
@Output() close: EventEmitter<any> = new EventEmitter();
9083

@@ -113,8 +106,6 @@ export class Notification {
113106

114107
/**
115108
* Emits close event.
116-
*
117-
* @memberof Notification
118109
*/
119110
onClose() {
120111
this.close.emit();

src/notification/toast.component.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@ import {
55
HostBinding
66
} from "@angular/core";
77

8-
import { NotificationContent, ToastContent } from "./notification-content.interface";
8+
import { ToastContent } from "./notification-content.interface";
99
import { Notification } from "./notification.component";
1010
import { ExperimentalService } from "./../experimental.module";
1111
import { NotificationDisplayService } from "./notification-display.service";
1212
import { I18n } from "./../i18n/i18n.module";
1313

1414
/**
15-
* Notification messages are displayed toward the top of the UI and do not interrupt user’s work.
16-
*
17-
* @export
18-
* @class Notification
15+
* Toast messages are displayed toward the top of the UI and do not interrupt user’s work.
1916
*/
2017
@Component({
2118
selector: "ibm-toast",
@@ -61,10 +58,7 @@ export class Toast extends Notification implements OnInit {
6158
/**
6259
* Can have `type`, `title`, `subtitle`, and `caption` members.
6360
*
64-
* `type` can be one of `"info"`, `"warning"`, `"danger"`, `"success"`
65-
*
66-
* `message` is message for notification to display
67-
*
61+
* `type` can be one of `"error"`, `"info"`, `"warning"`, or `"success"`
6862
*/
6963
@Input() notificationObj: ToastContent;
7064

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import {
2+
Component,
3+
HostBinding,
4+
Input,
5+
ViewChild,
6+
ElementRef,
7+
AfterContentInit
8+
} from "@angular/core";
9+
import { I18n } from "./../i18n/i18n.module";
10+
11+
@Component({
12+
selector: "ibm-expandable-tile",
13+
template: `
14+
<div
15+
class="bx--tile bx--tile--expandable"
16+
[ngClass]="{'bx--tile--is-expanded' : expanded}"
17+
[ngStyle]="{'max-height': expandedHeight + 'px'}"
18+
role="button"
19+
tabindex="0"
20+
(click)="onClick()">
21+
<button [attr.aria-label]="(expanded ? collapse : expand) | async" class="bx--tile__chevron">
22+
<svg *ngIf="!expanded" width="12" height="7" viewBox="0 0 12 7" role="img">
23+
<title>{{expand | async}}</title>
24+
<path fill-rule="nonzero" d="M6.002 5.55L11.27 0l.726.685L6.003 7 0 .685.726 0z"/>
25+
</svg>
26+
<svg *ngIf="expanded" width="12" height="7" viewBox="0 0 12 7" role="img">
27+
<title>{{collapse | async}}</title>
28+
<path fill-rule="nonzero" d="M6.002 5.55L11.27 0l.726.685L6.003 7 0 .685.726 0z"/>
29+
</svg>
30+
</button>
31+
<div class="bx--tile-content">
32+
<ng-content select=".bx--tile-content__above-the-fold"></ng-content>
33+
<ng-content select=".bx--tile-content__below-the-fold"></ng-content>
34+
</div>
35+
</div>
36+
`
37+
})
38+
export class ExpandableTile implements AfterContentInit {
39+
@Input() expanded = false;
40+
/**
41+
* Expects an object that contains some or all of:
42+
* ```
43+
* {
44+
* "EXPAND": "Expand",
45+
* "COLLAPSE": "Collapse",
46+
* }
47+
* ```
48+
*/
49+
@Input()
50+
set translations (value) {
51+
if (value.EXPAND) {
52+
this.expand.next(value.EXPAND);
53+
}
54+
if (value.COLLAPSE) {
55+
this.collapse.next(value.COLLAPSE);
56+
}
57+
}
58+
59+
tileMaxHeight = 0;
60+
element = this.elementRef.nativeElement;
61+
62+
expand = this.i18n.get("TILES.EXPAND");
63+
collapse = this.i18n.get("TILES.COLLAPSE");
64+
65+
constructor(protected i18n: I18n, protected elementRef: ElementRef) {}
66+
67+
ngAfterContentInit() {
68+
this.updateMaxHeight();
69+
}
70+
71+
get expandedHeight() {
72+
return this.tileMaxHeight + parseInt(getComputedStyle(this.element.querySelector(".bx--tile")).paddingBottom, 10);
73+
}
74+
75+
updateMaxHeight() {
76+
if (this.expanded) {
77+
this.tileMaxHeight = this.element.querySelector(".bx--tile-content").getBoundingClientRect().height;
78+
} else {
79+
this.tileMaxHeight = this.element.querySelector(".bx--tile-content__above-the-fold").getBoundingClientRect().height;
80+
}
81+
}
82+
83+
onClick() {
84+
this.expanded = !this.expanded;
85+
this.updateMaxHeight();
86+
}
87+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {
2+
Component,
3+
Input,
4+
Output,
5+
EventEmitter,
6+
ViewChild
7+
} from "@angular/core";
8+
import { NG_VALUE_ACCESSOR } from "@angular/forms";
9+
import { I18n } from "./../i18n/i18n.module";
10+
11+
@Component({
12+
selector: "ibm-selection-tile",
13+
template: `
14+
<label
15+
class="bx--tile bx--tile--selectable"
16+
tabindex="0"
17+
[for]="id"
18+
[ngClass]="{'bx--tile--is-selected' : selected}"
19+
[attr.aria-label]="i18n.get('TILES.TILE') | async">
20+
<input
21+
#input
22+
tabindex="-1"
23+
class="bx--tile-input"
24+
[id]="id"
25+
[type]="(multiple ? 'checkbox': 'radio')"
26+
[value]="value"
27+
[name]="name"
28+
(change)="onChange($event)"/>
29+
<div class="bx--tile__checkmark">
30+
<svg width="16" height="16" viewBox="0 0 16 16">
31+
<path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm3.646-10.854L6.75 10.043 4.354 7.646l-.708.708 3.104 3.103 5.604-5.603-.708-.708z"
32+
fill-rule="evenodd"/>
33+
</svg>
34+
</div>
35+
<div class="bx--tile-content">
36+
<ng-content></ng-content>
37+
</div>
38+
</label>
39+
`
40+
})
41+
export class SelectionTile {
42+
static tileCount = 0;
43+
/**
44+
* The unique id for the input.
45+
*/
46+
@Input() id = `tile-${SelectionTile.tileCount}`;
47+
/**
48+
* Updating the state of the input to match the state of the parameter passed in.
49+
* Set to `true` if this tile should be selected.
50+
*/
51+
@Input() set selected(value: boolean) {
52+
if (!this.input) { return; }
53+
this.input.nativeElement.checked = value ? true : null;
54+
}
55+
56+
get selected() {
57+
if (!this.input) { return; }
58+
return this.input.nativeElement.checked;
59+
}
60+
/**
61+
* The value for the tile. Returned via `ngModel` or `selected` event on the containing `TileGroup`.
62+
*/
63+
@Input() value: string;
64+
/**
65+
* Internal event used to notify the containing `TileGroup` of changes.
66+
*/
67+
@Output() change: EventEmitter<Event> = new EventEmitter();
68+
69+
/**
70+
* Set by the containing `TileGroup`. Used for the `name` property on the input.
71+
*/
72+
name: string;
73+
/**
74+
* Defines whether or not the `SelectionTile` supports selecting multiple tiles as opposed to single
75+
* tile selection.
76+
*/
77+
multiple: boolean;
78+
79+
@ViewChild("input") input;
80+
81+
constructor(public i18n: I18n) {
82+
SelectionTile.tileCount++;
83+
}
84+
85+
onChange(event) {
86+
this.change.emit(event);
87+
}
88+
}
89+
90+

src/tiles/tile-group.component.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import {
2+
Component,
3+
AfterContentInit,
4+
Input,
5+
Output,
6+
EventEmitter,
7+
HostBinding,
8+
ContentChildren,
9+
QueryList
10+
} from "@angular/core";
11+
import { SelectionTile } from "./selection-tile.component";
12+
import { NG_VALUE_ACCESSOR } from "@angular/forms";
13+
import { TileSelection } from "./tile-selection.interface";
14+
15+
@Component({
16+
selector: "ibm-tile-group",
17+
template: `<ng-content select="ibm-selection-tile"></ng-content>`,
18+
providers: [
19+
{
20+
provide: NG_VALUE_ACCESSOR,
21+
useExisting: TileGroup,
22+
multi: true
23+
}
24+
]
25+
})
26+
export class TileGroup implements AfterContentInit {
27+
static tileGroupCount = 0;
28+
/**
29+
* The tile group `name`
30+
*/
31+
@Input() name = `tile-group-${TileGroup.tileGroupCount}`;
32+
/**
33+
* Set to `true` to support multiple tile selection
34+
*/
35+
@Input() multiple = false;
36+
37+
/**
38+
* Emits an event when the tile selection changes.
39+
*
40+
* Emits an object that looks like:
41+
* ```javascript
42+
* {
43+
* value: "something",
44+
* selected: true,
45+
* name: "tile-group-1"
46+
* }
47+
* ```
48+
*/
49+
@Output() selected: EventEmitter<TileSelection> = new EventEmitter();
50+
51+
@HostBinding("class.bx--tile-group") tileGroupClass = true;
52+
53+
@ContentChildren(SelectionTile) selectionTiles: QueryList<SelectionTile>;
54+
55+
constructor() {
56+
TileGroup.tileGroupCount++;
57+
}
58+
59+
onChange = (_: any) => { };
60+
61+
onTouched = () => { };
62+
63+
ngAfterContentInit() {
64+
this.selectionTiles.forEach(tile => {
65+
tile.name = this.name;
66+
tile.change.subscribe(() => {
67+
this.selected.emit({
68+
value: tile.value,
69+
selected: tile.selected,
70+
name: this.name
71+
});
72+
this.onChange(tile.value);
73+
});
74+
tile.multiple = this.multiple;
75+
});
76+
}
77+
78+
writeValue(value: any) {
79+
if (!this.selectionTiles) { return; }
80+
this.selectionTiles.forEach(tile => {
81+
if (tile.value === value) {
82+
tile.selected = true;
83+
} else {
84+
tile.selected = false;
85+
}
86+
});
87+
}
88+
89+
registerOnChange(fn: any) {
90+
this.onChange = fn;
91+
}
92+
93+
registerOnTouched(fn: any) {
94+
this.onTouched = fn;
95+
}
96+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface TileSelection {
2+
value: string;
3+
selected: boolean;
4+
name: string;
5+
}

0 commit comments

Comments
 (0)