-
Notifications
You must be signed in to change notification settings - Fork 357
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(breadcrumbs): initial implementation *experimental* (#1183)
* feat(breadcrumbs): Initial scaffolding for breadcrumbs * feat(breadcrumbs): Checkpoint checkin with breadcrumbs showing up * feat(breadcrumbs): code cleanup and adding graying out to last element * feat(breadcrumbs): Adding themes to experimental area. Using scss to style breadcrumbs * add to demo * feat(breadcrumbs): Responsive Breadcrumbs, removes the left-most crumb as the window shrinks * Adding sandbox area with routes to test-beds * Using ngAfterContentChecked lifecycle method * Adding title to demo * Update documentation Readme with usage * Moving tab-select into separate demo directory * Unit Tests for Breadcrumbs * Unit Tests for Breadcrumbs * chore(breadcrumbs): Update code from code review * fix(breadcrumb): Fix unit test * chore(breadcrumbs): Use Subscription.EMPTY to avoid needing null checks * chore(breadcrumbs): remove console.log * chore(): updates on README Showcase get/set methods as properties since thats how they are used * chore(breadcrumbs): remove media usage from breadcrumbs to reduce noise * fix(breadcrumbs): stop click event on the breadcrumb separator this is done because the navigation or event shouldnt be triggered in that scenario
- Loading branch information
1 parent
d9d8055
commit 256491e
Showing
30 changed files
with
712 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# td-breadcrumbs (experimental) | ||
|
||
`td-breadcrumbs` element generates breadcrumbs for navigation. Handles Responsive by removing breadcrumbs from the beginning of the list as allowable space decreases. | ||
|
||
## API Summary | ||
|
||
#### Inputs | ||
|
||
+ separatorIcon?: string | ||
+ Sets the icon url shown between breadcrumbs. Defaults to right chevron. | ||
|
||
#### Methods | ||
|
||
+ count: number | ||
+ The total count of individual breadcrumbs (read only) | ||
|
||
#### Attributes | ||
|
||
+ hiddenBreadcrumbs: TdBreadcrumbComponent[] | ||
+ Array of currently hidden breadcrumbs (responsive) | ||
|
||
# td-breadcrumb | ||
|
||
`td-breadcrumb` element generates an individual breadcrumb component. | ||
|
||
## API Summary | ||
|
||
#### Methods | ||
|
||
+ displayCrumb: boolean | ||
+ Whether to display the individual breadcrumb or not | ||
+ width: number | ||
+ The current width of the individual breadcrumb (read only) | ||
|
||
## Setup | ||
|
||
Import the [CovalentBreadcrumbsModule] in your NgModule: | ||
|
||
```typescript | ||
import { CovalentBreadcrumbsModule } from '@covalent/experimental/breadcrumbs'; | ||
@NgModule({ | ||
imports: [ | ||
CovalentBreadcrumbsModule, | ||
... | ||
], | ||
... | ||
}) | ||
export class MyModule {} | ||
``` | ||
|
||
## Usage | ||
|
||
Basic Example: | ||
|
||
```html | ||
<td-breadcrumbs class="pad-left"> | ||
<a td-breadcrumb [routerLink]="'/'">Home</a> | ||
<a td-breadcrumb [routerLink]="'/layouts'">Layouts</a> | ||
<a td-breadcrumb [routerLink]="'/layouts2'">Layouts2</a> | ||
<a td-breadcrumb [routerLink]="'/layouts3'">Layouts3</a> | ||
<td-breadcrumb class="tc-grey-500">Manage List</td-breadcrumb> | ||
</td-breadcrumbs> | ||
``` | ||
|
||
Example with all inputs/outputs: | ||
|
||
```html | ||
<td-breadcrumbs #breadcrumbs separatorIcon="motorcycle"> | ||
<a td-breadcrumb [routerLink]="'/'">Home</a> | ||
<a td-breadcrumb [routerLink]="'/layouts'">Layouts</a> | ||
<a td-breadcrumb [routerLink]="'/layouts2'">Layouts2</a> | ||
<a td-breadcrumb [routerLink]="'/layouts3'">Layouts3</a> | ||
<td-breadcrumb class="tc-grey-500">Manage List</td-breadcrumb> | ||
</td-breadcrumbs> | ||
<mat-divider></mat-divider> | ||
<div> | ||
Total Breadcrumbs Count: {{breadcrumbs.count}} | ||
</div> | ||
<div> | ||
Hidden Breadcrumbs Count (shrink window to see): {{breadcrumbs.hiddenBreadcrumbs.length}} | ||
</div> | ||
<ng-template let-breadcrumb let-index="index" ngFor [ngForOf]="breadcrumbs.hiddenBreadcrumbs"> | ||
<div> | ||
<p>Breadcrumb Number: {{index}}</p> | ||
<p>Breadcrumb Width: {{breadcrumb?.width}}</p> | ||
<mat-divider></mat-divider> | ||
</div> | ||
</ng-template> | ||
``` |
11 changes: 11 additions & 0 deletions
11
src/platform/experimental/breadcrumbs/breadcrumb/_breadcrumb-theme.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
@mixin td-breadcrumb-theme($theme) { | ||
$foreground: map-get($theme, foreground); | ||
|
||
td-breadcrumb { | ||
&:last-of-type { | ||
color: mat-color($foreground, disabled); | ||
cursor: default; | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/platform/experimental/breadcrumbs/breadcrumb/breadcrumb.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<span *ngIf="displayCrumb" class="td-breadcrumb"> | ||
<ng-content></ng-content> | ||
<mat-icon *ngIf="_displayIcon" | ||
[style.cursor]="'default'" | ||
(click)="_handleIconClick($event)"> | ||
{{separatorIcon}} | ||
</mat-icon> | ||
</span> |
22 changes: 22 additions & 0 deletions
22
src/platform/experimental/breadcrumbs/breadcrumb/breadcrumb.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
:host { | ||
.td-breadcrumb { | ||
height: 48px; | ||
box-sizing: border-box; | ||
flex-direction: row; | ||
align-items: center; | ||
align-content: center; | ||
max-width: 100%; | ||
justify-content: flex-end; | ||
::ng-deep > * { | ||
margin: 0 10px; | ||
} | ||
} | ||
mat-icon.material-icons.mat-icon { | ||
display: inline-flex; | ||
vertical-align: middle; | ||
} | ||
&.mat-button { | ||
min-width: 0; | ||
padding: 0; | ||
} | ||
} |
Empty file.
72 changes: 72 additions & 0 deletions
72
src/platform/experimental/breadcrumbs/breadcrumb/breadcrumb.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { | ||
Component, | ||
ElementRef, | ||
Renderer2, | ||
HostBinding, | ||
AfterViewInit, | ||
ChangeDetectionStrategy, | ||
ChangeDetectorRef, | ||
} from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'td-breadcrumb, a[td-breadcrumb]', | ||
styleUrls: ['./breadcrumb.component.scss'], | ||
templateUrl: './breadcrumb.component.html', | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
}) | ||
export class TdBreadcrumbComponent implements AfterViewInit { | ||
|
||
private _displayCrumb: boolean = true; | ||
private _width: number = 0; | ||
// Sets the icon url shown between breadcrumbs. Defaults to right chevron | ||
separatorIcon: string = 'navigate_next'; | ||
// Should show the right chevron or not before the label | ||
_displayIcon: boolean = true; | ||
|
||
get displayCrumb(): boolean { | ||
return this._displayCrumb; | ||
} | ||
|
||
/** | ||
* Whether to display the crumb or not | ||
*/ | ||
set displayCrumb(shouldDisplay: boolean) { | ||
this._displayCrumb = shouldDisplay; | ||
this._changeDetectorRef.markForCheck(); | ||
} | ||
|
||
/** | ||
* Width of the DOM element of the crumb | ||
*/ | ||
get width(): number { | ||
return this._width; | ||
} | ||
|
||
// Set the display to none on the component, just in case the end user is hiding | ||
// and showing them instead of the component doing itself for reasons like responsive | ||
@HostBinding('style.display') | ||
private get displayBinding(): string { | ||
return this._displayCrumb ? undefined : 'none'; | ||
} | ||
|
||
constructor(private _elementRef: ElementRef, | ||
private _renderer: Renderer2, | ||
private _changeDetectorRef: ChangeDetectorRef) { | ||
this._renderer.addClass(this._elementRef.nativeElement, 'mat-button'); | ||
} | ||
|
||
ngAfterViewInit(): void { | ||
// set the width from the actual rendered DOM element | ||
this._width = (<HTMLElement>this._elementRef.nativeElement).getBoundingClientRect().width; | ||
this._changeDetectorRef.markForCheck(); | ||
} | ||
|
||
/** | ||
* Stop click propagation when clicking on icon | ||
*/ | ||
_handleIconClick(event: Event): void { | ||
event.stopPropagation(); | ||
event.preventDefault(); | ||
} | ||
|
||
} |
3 changes: 3 additions & 0 deletions
3
src/platform/experimental/breadcrumbs/breadcrumbs.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div class="td-breadcrumbs"> | ||
<ng-content></ng-content> | ||
</div> |
5 changes: 5 additions & 0 deletions
5
src/platform/experimental/breadcrumbs/breadcrumbs.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
:host { | ||
.td-breadcrumbs { | ||
white-space: nowrap; | ||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
src/platform/experimental/breadcrumbs/breadcrumbs.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { | ||
TestBed, | ||
inject, | ||
async, | ||
ComponentFixture, | ||
} from '@angular/core/testing'; | ||
import { RouterTestingModule } from '@angular/router/testing'; | ||
import { | ||
Component, | ||
DebugElement, | ||
} from '@angular/core'; | ||
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; | ||
import { By } from '@angular/platform-browser'; | ||
import { | ||
CovalentBreadcrumbsModule, | ||
} from './public-api'; | ||
import { | ||
TdBreadcrumbsComponent, | ||
} from './breadcrumbs.component'; | ||
|
||
@Component({ | ||
selector: 'fake', | ||
template: `<router-outlet></router-outlet><div>fake</div>`, | ||
}) | ||
export class FakeComponent { | ||
} | ||
|
||
describe('Component: Breadcrumbs', () => { | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [ | ||
TdBreadcrumbsTestComponent, | ||
FakeComponent, | ||
], | ||
imports: [ | ||
NoopAnimationsModule, | ||
RouterTestingModule.withRoutes([ | ||
{ path: '', component: FakeComponent }, | ||
{ path: 'layouts', component: FakeComponent }, | ||
{ path: 'layouts2', component: FakeComponent }, | ||
{ path: 'layouts3', component: FakeComponent }, | ||
]), | ||
CovalentBreadcrumbsModule, | ||
], | ||
}); | ||
TestBed.compileComponents(); | ||
})); | ||
|
||
it('should render 5 Breadcrumbs', | ||
async(inject([], () => { | ||
let fixture: ComponentFixture<any> = TestBed.createComponent(TdBreadcrumbsTestComponent); | ||
fixture.detectChanges(); | ||
fixture.whenStable().then(() => { | ||
let breadcrumbs: TdBreadcrumbsComponent = fixture.debugElement.query(By.directive(TdBreadcrumbsComponent)).componentInstance; | ||
expect(breadcrumbs.count).toBe(5); | ||
}); | ||
}), | ||
)); | ||
|
||
it('should change the separatorIcon', | ||
async(inject([], () => { | ||
let fixture: ComponentFixture<any> = TestBed.createComponent(TdBreadcrumbsTestComponent); | ||
let component: TdBreadcrumbsTestComponent = fixture.debugElement.componentInstance; | ||
component.separatorIcon = 'flight_land'; | ||
fixture.detectChanges(); | ||
fixture.whenStable().then(() => { | ||
expect(fixture.debugElement.queryAll(By.css('.td-breadcrumb'))[1].nativeElement.innerHTML.indexOf('flight_land')).toBeGreaterThan(-1); | ||
}); | ||
}), | ||
)); | ||
|
||
it('should resize window and hide breadcrumbs', | ||
async(inject([], () => { | ||
let fixture: ComponentFixture<any> = TestBed.createComponent(TdBreadcrumbsTestComponent); | ||
fixture.detectChanges(); | ||
fixture.whenStable().then(() => { | ||
fixture.debugElement.query(By.directive(TdBreadcrumbsComponent)).nativeElement.parentElement.style.width = '300px'; | ||
window.dispatchEvent(new Event('resize')); | ||
fixture.detectChanges(); | ||
fixture.whenStable().then(() => { | ||
let breadcrumbs: TdBreadcrumbsComponent = fixture.debugElement.query(By.directive(TdBreadcrumbsComponent)).componentInstance; | ||
expect(breadcrumbs.hiddenBreadcrumbs.length).toBe(2); | ||
}); | ||
}); | ||
}), | ||
)); | ||
}); | ||
|
||
@Component({ | ||
selector: 'td-breadcrumbs-test', | ||
template: ` | ||
<div style="width: {{width}}"> | ||
<td-breadcrumbs #breadcrumbs class="pad-left" separatorIcon="{{separatorIcon}}"> | ||
<a td-breadcrumb [routerLink]="'/'">Home</a> | ||
<a td-breadcrumb [routerLink]="'/layouts'">Layouts</a> | ||
<a td-breadcrumb [routerLink]="'/layouts2'">Layouts2</a> | ||
<a td-breadcrumb [routerLink]="'/layouts3'">Layouts3</a> | ||
<td-breadcrumb class="tc-grey-500">Manage List</td-breadcrumb> | ||
</td-breadcrumbs> | ||
</div> | ||
`, | ||
}) | ||
class TdBreadcrumbsTestComponent { | ||
separatorIcon: string = 'motorcycle'; | ||
} |
Oops, something went wrong.