Skip to content

Commit 0844ff1

Browse files
authored
Merge branch 'master' into table-toolbar
2 parents 5e8755d + 93f696e commit 0844ff1

File tree

4 files changed

+84
-17
lines changed

4 files changed

+84
-17
lines changed

src/dialog/dialog-config.interface.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ export interface DialogConfig {
1414
content: string | TemplateRef<any>;
1515
/**
1616
* Parameter for triggering `Dialog` display.
17-
* With the release of v2.0 the type will just be "click" or "hover".
1817
*/
1918
trigger: "click" | "hover" | "mouseenter";
19+
/**
20+
* Parameter for triggering the `Dialog` close event.
21+
*/
22+
closeTrigger: "mouseout" | "mouseleave";
2023
/**
2124
* Parameter defining the placement in which the `Dialog` appears.
2225
* @type {Placement}

src/dialog/dialog.directive.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,35 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
3636
static dialogCounter = 0;
3737
/**
3838
* Title for the dialog
39-
* @type {string}
4039
*/
4140
@Input() title = "";
4241
/**
4342
* Dialog body content.
44-
* @type {(string | TemplateRef<any>)}
4543
*/
4644
@Input() ibmDialog: string | TemplateRef<any>;
4745
/**
4846
* Defines how the Dialog is triggered.(Hover and click behave the same on mobile - both respond to a single tap)
49-
* @type {("click" | "hover" | "mouseenter")}
5047
*/
5148
@Input() trigger: "click" | "hover" | "mouseenter" = "click";
49+
/**
50+
* Defines how the Dialog close event is triggered.
51+
*
52+
* [See here](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseleave_event)
53+
* for more on the difference between `mouseleave` and `mouseout`.
54+
*
55+
* Defaults to `click` when `trigger` is set to `click`.
56+
*/
57+
@Input() closeTrigger: "mouseout" | "mouseleave" = "mouseleave";
5258
/**
5359
* Placement of the dialog, usually relative to the element the directive is on.
5460
*/
5561
@Input() placement = "left";
5662
/**
5763
* Class to add to the dialog container
58-
* @type {string}
5964
*/
6065
@Input() wrapperClass: string;
6166
/**
6267
* Spacing between the dialog and it's triggering element
63-
* @type {number}
6468
*/
6569
@Input() gap = 0;
6670
/**
@@ -117,7 +121,6 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
117121

118122
/**
119123
* Overrides 'touchstart' event to trigger a toggle on the Dialog.
120-
* @param {any} evt
121124
*/
122125
@HostListener("touchstart", ["$event"])
123126
onTouchStart(evt) {
@@ -135,6 +138,7 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
135138
parentRef: this.elementRef,
136139
gap: this.gap,
137140
trigger: this.trigger,
141+
closeTrigger: this.closeTrigger,
138142
appendInline: this.appendInline,
139143
wrapperClass: this.wrapperClass,
140144
data: this.data
@@ -160,7 +164,7 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
160164
// bind events for hovering or clicking the host
161165
if (this.trigger === "hover" || this.trigger === "mouseenter") {
162166
fromEvent(this.elementRef.nativeElement, "mouseenter").subscribe(() => this.toggle());
163-
fromEvent(this.elementRef.nativeElement, "mouseout").subscribe(() => this.close());
167+
fromEvent(this.elementRef.nativeElement, this.closeTrigger).subscribe(() => this.close());
164168
fromEvent(this.elementRef.nativeElement, "focus").subscribe(() => this.open());
165169
fromEvent(this.elementRef.nativeElement, "blur").subscribe(() => this.close());
166170
} else {
@@ -231,7 +235,6 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
231235
/**
232236
* Empty method for child classes to override and specify additional init steps.
233237
* Run after DialogDirective completes it's ngOnInit.
234-
* @protected
235238
*/
236239
protected onDialogInit() {}
237240
}

src/dropdown/dropdown.component.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
ViewChild,
1010
AfterContentInit,
1111
HostListener,
12-
OnDestroy
12+
OnDestroy,
13+
TemplateRef
1314
} from "@angular/core";
1415
import { NG_VALUE_ACCESSOR } from "@angular/forms";
1516

@@ -66,7 +67,12 @@ import { DropdownService } from "./dropdown.service";
6667
<path d="M12 4.7l-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8z"></path>
6768
</svg>
6869
</div>
69-
<span class="bx--list-box__label">{{getDisplayValue() | async}}</span>
70+
<span *ngIf="isRenderString()" class="bx--list-box__label">{{getDisplayStringValue() | async}}</span>
71+
<ng-template
72+
*ngIf="!isRenderString()"
73+
[ngTemplateOutletContext]="getRenderTemplateContext()"
74+
[ngTemplateOutlet]="displayValue">
75+
</ng-template>
7076
<ibm-icon-chevron-down16
7177
*ngIf="!skeleton"
7278
class="bx--list-box__menu-icon"
@@ -97,9 +103,9 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
97103
*/
98104
@Input() placeholder = "";
99105
/**
100-
* The selected value from the `Dropdown`.
106+
* The selected value from the `Dropdown`. Can be a string or template.
101107
*/
102-
@Input() displayValue = "";
108+
@Input() displayValue: string | TemplateRef<any> = "";
103109
/**
104110
* Size to render the dropdown field.
105111
*/
@@ -358,23 +364,41 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
358364
* if there is just a selection the ListItem content property will be returned,
359365
* otherwise the placeholder will be returned.
360366
*/
361-
getDisplayValue(): Observable<string> {
367+
getDisplayStringValue(): Observable<string> {
362368
if (!this.view) {
363369
return;
364370
}
365371
let selected = this.view.getSelected();
366-
if (selected && !this.displayValue) {
372+
if (selected && (!this.displayValue || !this.isRenderString())) {
367373
if (this.type === "multi") {
368374
return of(this.placeholder);
369375
} else {
370376
return of(selected[0].content);
371377
}
372-
} else if (selected) {
373-
return of(this.displayValue);
378+
} else if (selected && this.isRenderString()) {
379+
return of(this.displayValue as string);
374380
}
375381
return of(this.placeholder);
376382
}
377383

384+
isRenderString(): boolean {
385+
return typeof this.displayValue === "string";
386+
}
387+
388+
getRenderTemplateContext() {
389+
if (!this.view) {
390+
return;
391+
}
392+
let selected = this.view.getSelected();
393+
if (this.type === "multi") {
394+
return {items: selected};
395+
} else if (selected && selected.length > 0) {
396+
return {item: selected[0]}; // this is to be compatible with the dropdown-list template
397+
} else {
398+
return {};
399+
}
400+
}
401+
378402
getSelectedCount(): number {
379403
if (this.view.getSelected()) {
380404
return this.view.getSelected().length;

src/dropdown/dropdown.stories.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,43 @@ storiesOf("Dropdown", module)
118118
theme: select("theme", ["dark", "light"], "dark")
119119
}
120120
}))
121+
.add("With Template", () => ({
122+
template: `
123+
<div style="width: 300px;">
124+
<ibm-dropdown
125+
[theme]="theme"
126+
placeholder="Select"
127+
[displayValue]="dropdownRenderer"
128+
[disabled]="disabled"
129+
(selected)="selected($event)"
130+
(onClose)="onClose($event)">
131+
<ibm-dropdown-list [items]="items" [listTpl]="dropdownRenderer"></ibm-dropdown-list>
132+
</ibm-dropdown>
133+
<ng-template #dropdownRenderer let-item="item">
134+
<div *ngIf="item && item.content" style="font-size: 14px;">
135+
<svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg"
136+
width="16" height="16" viewBox="0 0 16 16" aria-hidden="true" style="will-change: transform;">
137+
<path d="M9.3 3.7l3.8 3.8H1v1h12.1l-3.8 3.8.7.7 5-5-5-5z"></path>
138+
</svg>
139+
&nbsp;{{item.content}}
140+
</div>
141+
</ng-template>
142+
</div>
143+
`,
144+
props: {
145+
disabled: boolean("disabled", false),
146+
items: object("items", [
147+
{ content: "one", selected: true },
148+
{ content: "two" },
149+
{ content: "three" },
150+
{ content: "four" }
151+
]),
152+
selected: action("Selected fired for dropdown"),
153+
onClose: action("Dropdown closed"),
154+
theme: select("theme", ["dark", "light"], "dark")
155+
}
156+
157+
}))
121158
.add("Skeleton", () => ({
122159
template: `
123160
<div style="width: 300px">

0 commit comments

Comments
 (0)