Skip to content

Commit

Permalink
Merge branch 'master' into issue_#1106_v4
Browse files Browse the repository at this point in the history
  • Loading branch information
cal-smith committed Jun 3, 2020
2 parents ecd41a1 + d06caac commit 48a8288
Show file tree
Hide file tree
Showing 24 changed files with 241 additions and 70 deletions.
11 changes: 7 additions & 4 deletions src/combobox/combobox.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,9 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit {
writeValue(value: any) {
if (this.type === "single") {
this.view.propagateSelected([value]);
this.showClearButton = !!(value && this.view.getSelected().length);
} else {
this.view.propagateSelected(value);
this.view.propagateSelected(value ? value : [""]);
}
this.updateSelected();
}
Expand Down Expand Up @@ -578,9 +579,11 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit {
const selected = this.view.getSelected();
if (this.type === "multi" ) {
this.updatePills();
} else if (selected && selected[0]) {
this.selectedValue = selected[0].content;
this.propagateChangeCallback(selected[0]);
} else if (selected) {
const value = selected[0] ? selected[0].content : "";
const changeCallbackValue = selected[0] ? selected[0] : "";
this.selectedValue = value;
this.propagateChangeCallback(changeCallbackValue);
}
}
}
15 changes: 14 additions & 1 deletion src/datepicker/datepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,19 @@ export class DatePicker implements OnDestroy, OnChanges, AfterViewChecked, After
this.updateClassNames();
this.updateCalendarListeners();
},
onClose: () => {
// This makes sure that the `flatpickrInstance selectedDates` are in sync with the values of
// the inputs when the calendar closes.
if (this.range && this.flatpickrInstance) {
const inputValue = this.input.input.nativeElement.value;
const rangeInputValue = this.rangeInput.input.nativeElement.value;
// Range needs both dates to properly set the selected dates on the calendar.
if (inputValue && rangeInputValue) {
const parseDate = (date: string) => this.flatpickrInstance.parseDate(date, this.dateFormat);
this.setDateValues([parseDate(inputValue), parseDate(rangeInputValue)]);
}
}
},
value: this.value
};

Expand Down Expand Up @@ -306,7 +319,7 @@ export class DatePicker implements OnDestroy, OnChanges, AfterViewChecked, After
* Handles the `valueChange` event from the range input
*/
onRangeValueChange(event: string) {
if (this.isFlatpickrLoaded()) {
if (this.isFlatpickrLoaded() && this.flatpickrInstance.isOpen) {
const date = this.flatpickrInstance.parseDate(event, this.dateFormat);
this.setDateValues([this.flatpickrInstance.selectedDates[0], date]);
this.doSelect(this.flatpickrInstance.selectedDates);
Expand Down
4 changes: 4 additions & 0 deletions src/dialog/dialog-config.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ export interface DialogConfig {
* This specifies any vertical and horizontal offset for the position of the dialog
*/
offset?: { x: number, y: number };
/**
* This prevents the dialog from being toggled
*/
disabled?: boolean;
}
9 changes: 7 additions & 2 deletions src/dialog/dialog.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
@Input() data = {};

@Input() @HostBinding("attr.aria-expanded") isOpen = false;
/**
* This prevents the dialog from being toggled
*/
@Input() disabled = false;
/**
* Config object passed to the rendered component
*/
Expand Down Expand Up @@ -144,7 +148,8 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
shouldClose: () => true,
appendInline: this.appendInline,
wrapperClass: this.wrapperClass,
data: this.data
data: this.data,
disabled: this.disabled
};

if (changes.isOpen) {
Expand Down Expand Up @@ -221,7 +226,7 @@ export class DialogDirective implements OnInit, OnDestroy, OnChanges {
*/
open() {
// don't allow dialogs to be opened if they're already open
if (this.dialogRef) { return; }
if (this.dialogRef || this.disabled) { return; }

// actually open the dialog, emit events, and set the open state
this.dialogRef = this.dialogService.open(this.viewContainerRef, this.dialogConfig);
Expand Down
29 changes: 25 additions & 4 deletions src/dialog/tooltip/ellipsis-tooltip.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
ElementRef,
Injector,
ComponentFactoryResolver,
ViewContainerRef
ViewContainerRef,
HostListener
} from "@angular/core";
import { TooltipDirective } from "./tooltip.directive";
import { DialogService } from "./../dialog.service";
Expand All @@ -31,16 +32,36 @@ import { Tooltip } from "./tooltip.component";
})
export class EllipsisTooltip extends TooltipDirective {
/**
* Toggles tooltip in view if text is truncated.
* If text is truncated, this appends the text to the dialog as content.
* @returns null
* @memberof EllipsisTooltip
*/
toggle() {
updateTooltipContent() {
if (this.elementRef.nativeElement.scrollWidth <= this.elementRef.nativeElement.offsetWidth) {
this.disabled = true;
return;
}

this.disabled = false;
this.dialogConfig.content = this.elementRef.nativeElement.innerText;
super.toggle();
}

@HostListener("click")
onClick() {
if (this.trigger === "click") {
this.updateTooltipContent();
}
}

@HostListener("mouseenter")
onHover() {
if (this.trigger === "hover" || this.trigger === "mouseenter") {
this.updateTooltipContent();
}
}

@HostListener("focus")
onFocus() {
this.updateTooltipContent();
}
}
32 changes: 32 additions & 0 deletions src/dialog/tooltip/tooltip.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,38 @@ storiesOf("Components|Tooltip", module)
isOpen: boolean("isOpen", false)
}
}))
.add("Ellipsis tooltip", () => ({
styles: [`
.fullText {
white-space: nowrap;
display: inline-block;
}
.overflowText {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100px;
display: inline-block;
}
`],
template: `
<span
class="ellipsis"
[ngClass]="{
'fullText': showFullText,
'overflowText': !showFullText
}"
trigger="hover"
[placement]="'bottom'"
ibmEllipsisTooltip>
Tooltip for ellipsis because I can and I am really really long
</span>
<ibm-placeholder></ibm-placeholder>
`,
props: {
showFullText: boolean("Show full text", false)
}
}))
.add("Documentation", () => ({
template: `
<ibm-documentation src="documentation/directives/TooltipDirective.html"></ibm-documentation>
Expand Down
2 changes: 1 addition & 1 deletion src/dropdown/dropdown.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import { hasScrollableParents } from "../utils";
@Component({
selector: "ibm-dropdown",
template: `
<label *ngIf="label" [for]="id" class="bx--label">
<label *ngIf="label" class="bx--label">
<ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container>
<ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template>
</label>
Expand Down
19 changes: 10 additions & 9 deletions src/modal/alert-modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
Component,
Inject,
ViewChild,
AfterViewInit
AfterViewInit,
Optional
} from "@angular/core";
import { BaseModal } from "./base-modal.class";

Expand Down Expand Up @@ -82,14 +83,14 @@ export class AlertModal extends BaseModal implements AfterViewInit {
* Creates an instance of `AlertModal`.
*/
constructor(
@Inject("type") public type = "default",
@Inject("label") public label: string,
@Inject("title") public title: string,
@Inject("content") public content: string,
@Inject("size") public size: string,
@Inject("hasScrollingContent") public hasScrollingContent: boolean = null,
@Inject("buttons") public buttons = [],
@Inject("close") public onClose: Function
@Optional() @Inject("type") public type = "default",
@Optional() @Inject("label") public label: string,
@Optional() @Inject("title") public title: string,
@Optional() @Inject("content") public content: string,
@Optional() @Inject("size") public size: string,
@Optional() @Inject("hasScrollingContent") public hasScrollingContent: boolean = null,
@Optional() @Inject("buttons") public buttons = [],
@Optional() @Inject("close") public onClose: Function
) {
super();
for (let i = 0; i < this.buttons.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion src/modal/modal-header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { ExperimentalService } from "./../experimental.service";
class="bx--modal-close"
[attr.aria-label]="closeLabel"
(click)="onClose()">
<ibm-icon-close size="16" class="bx--modal-close__icon"></ibm-icon-close>
<svg ibmIconClose size="20" class="bx--modal-close__icon"></svg>
</button>
</header>
Expand Down
21 changes: 15 additions & 6 deletions src/notification/notification.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,30 @@ import { of, isObservable, Subject } from "rxjs";
selector: "ibm-notification",
template: `
<div class="bx--inline-notification__details">
<ibm-icon-error-filled
<svg
ibmIconErrorFilled
size="16"
*ngIf="notificationObj.type === 'error'"
class="bx--inline-notification__icon">
</ibm-icon-error-filled>
<ibm-icon-warning-filled
</svg>
<svg
ibmIconWarningFilled
size="16"
*ngIf="notificationObj.type === 'warning'"
class="bx--inline-notification__icon">
</ibm-icon-warning-filled>
<ibm-icon-checkmark-filled
</svg>
<svg
ibmIconCheckmarkFilled
size="16"
*ngIf="notificationObj.type === 'success'"
class="bx--inline-notification__icon">
</ibm-icon-checkmark-filled>
</svg>
<svg
ibmIconInformationFilled
size="16"
*ngIf="notificationObj.type === 'info'"
class="bx--inline-notification__icon">
</svg>
<div class="bx--inline-notification__text-wrapper">
<p *ngIf="!notificationObj.template" ibmNotificationTitle [innerHTML]="notificationObj.title"></p>
<p *ngIf="!notificationObj.template" ibmNotificationSubtitle [innerHTML]="notificationObj.message"></p>
Expand Down
6 changes: 4 additions & 2 deletions src/notification/notification.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
CloseModule,
ErrorFilledModule,
CheckmarkFilledModule,
WarningFilledModule
WarningFilledModule,
InformationFilledModule
} from "@carbon/icons-angular";

import { Toast } from "./toast.component";
Expand Down Expand Up @@ -48,7 +49,8 @@ import { ExperimentalModule } from "./../experimental.module";
CloseModule,
ErrorFilledModule,
CheckmarkFilledModule,
WarningFilledModule
WarningFilledModule,
InformationFilledModule
],
providers: [NotificationService, NotificationDisplayService]
})
Expand Down
21 changes: 15 additions & 6 deletions src/notification/toast.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,30 @@ import { I18n } from "./../i18n/index";
@Component({
selector: "ibm-toast",
template: `
<ibm-icon-error-filled
<svg
ibmIconErrorFilled
size="16"
*ngIf="notificationObj.type === 'error'"
class="bx--toast-notification__icon">
</ibm-icon-error-filled>
<ibm-icon-warning-filled
</svg>
<svg
ibmIconWarningFilled
size="16"
*ngIf="notificationObj.type === 'warning'"
class="bx--toast-notification__icon">
</ibm-icon-warning-filled>
<ibm-icon-checkmark-filled
</svg>
<svg
ibmIconCheckmarkFilled
size="16"
*ngIf="notificationObj.type === 'success'"
class="bx--toast-notification__icon">
</ibm-icon-checkmark-filled>
</svg>
<svg
ibmIconInformationFilled
size="16"
*ngIf="notificationObj.type === 'info'"
class="bx--toast-notification__icon">
</svg>
<div class="bx--toast-notification__details">
<h3 *ngIf="!notificationObj.template" ibmToastTitle [innerHTML]="notificationObj.title"></h3>
<p *ngIf="!notificationObj.template" ibmToastSubtitle [innerHTML]="notificationObj.subtitle"></p>
Expand Down
6 changes: 5 additions & 1 deletion src/radio/radio.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import { RadioChange } from "./radio-change.class";
[required]="required"
[value]="value"
[attr.aria-labelledby]="ariaLabelledby"
(change)="onChange($event)">
(change)="onChange($event)"
(click)="onClick($event)">
<div *ngIf="skeleton" class="bx--radio-button bx--skeleton"></div>
<label
class="bx--radio-button__label"
Expand Down Expand Up @@ -131,6 +132,9 @@ export class Radio {
*/
onChange(event: Event) {
event.stopPropagation();
}

onClick(event: Event) {
this.checked = (event.target as HTMLInputElement).checked;
const radioEvent = new RadioChange(this, this.value);
this.change.emit(radioEvent);
Expand Down
1 change: 1 addition & 0 deletions src/search/search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ export class Search implements ControlValueAccessor {
focusOut(event) {
this.onTouched();
if (this.toolbar &&
this.inputRef &&
this.inputRef.nativeElement.value === "" &&
event.relatedTarget === null) {
this.active = false;
Expand Down
3 changes: 2 additions & 1 deletion src/table/stories/app-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function sort(model, index: number) {
[size]="size"
[skeleton]="skeleton"
[showSelectionColumn]="showSelectionColumn"
[enableSingleSelect]="false"
[enableSingleSelect]="enableSingleSelect"
(rowClick)="onRowClick($event)"
[sortable]="sortable"
[stickyHeader]="stickyHeader"
Expand All @@ -41,6 +41,7 @@ export class TableStory implements OnInit, OnChanges {
@Input() model = new TableModel();
@Input() size = "md";
@Input() showSelectionColumn = true;
@Input() enableSingleSelect = false;
@Input() striped = true;
@Input() sortable = true;
@Input() isDataGrid = false;
Expand Down
5 changes: 4 additions & 1 deletion src/table/table-adapter.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,11 @@ export class TableDomAdapter implements TableAdapter {
*/
findColumnIndex(cell: HTMLTableCellElement): number {
const row = this.getRow(this.findRowIndex(cell));
if (!row) {
return;
}
// if the cell has linked headers we can do a more accurate lookup
if (cell.headers) {
if (cell && cell.headers) {
const ids = cell.headers.split(" ");
const headerRows = Array.from(this.tableElement.tHead.rows);
const indexes = [];
Expand Down
Loading

0 comments on commit 48a8288

Please sign in to comment.