mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-02 18:17:46 +01:00
[EC-937] Pre-merge breadcrumbs into master (#4420)
original implementation from ef20ee1882
(https://github.com/bitwarden/clients/pull/3762)
This commit is contained in:
parent
6b1a72851a
commit
f4219bada9
@ -0,0 +1,4 @@
|
|||||||
|
<ng-template>
|
||||||
|
<i *ngIf="icon" class="bwi {{ icon }} tw-mr-1" aria-hidden="true"></i>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</ng-template>
|
25
libs/components/src/breadcrumbs/breadcrumb.component.ts
Normal file
25
libs/components/src/breadcrumbs/breadcrumb.component.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-breadcrumb",
|
||||||
|
templateUrl: "./breadcrumb.component.html",
|
||||||
|
})
|
||||||
|
export class BreadcrumbComponent {
|
||||||
|
@Input()
|
||||||
|
icon?: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
route?: string | any[] = undefined;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
queryParams?: Record<string, string> = {};
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
click = new EventEmitter();
|
||||||
|
|
||||||
|
@ViewChild(TemplateRef, { static: true }) content: TemplateRef<unknown>;
|
||||||
|
|
||||||
|
onClick(args: unknown) {
|
||||||
|
this.click.next(args);
|
||||||
|
}
|
||||||
|
}
|
81
libs/components/src/breadcrumbs/breadcrumbs.component.html
Normal file
81
libs/components/src/breadcrumbs/breadcrumbs.component.html
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<ng-container *ngFor="let breadcrumb of beforeOverflow; let last = last">
|
||||||
|
<ng-container *ngIf="breadcrumb.route">
|
||||||
|
<a
|
||||||
|
bitLink
|
||||||
|
linkType="primary"
|
||||||
|
class="tw-my-2 tw-inline-block"
|
||||||
|
[routerLink]="breadcrumb.route"
|
||||||
|
[queryParams]="breadcrumb.queryParams"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||||
|
</a>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!breadcrumb.route">
|
||||||
|
<button
|
||||||
|
bitLink
|
||||||
|
linkType="primary"
|
||||||
|
class="tw-my-2 tw-inline-block"
|
||||||
|
(click)="breadcrumb.onClick($event)"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
<i *ngIf="!last" class="bwi bwi-angle-right tw-mx-1.5 tw-text-main"></i>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="hasOverflow">
|
||||||
|
<i *ngIf="beforeOverflow.length > 0" class="bwi bwi-angle-right tw-mx-1.5 tw-text-main"></i>
|
||||||
|
|
||||||
|
<button
|
||||||
|
bitIconButton="bwi-ellipsis-h"
|
||||||
|
[bitMenuTriggerFor]="overflowMenu"
|
||||||
|
size="small"
|
||||||
|
aria-haspopup
|
||||||
|
></button>
|
||||||
|
|
||||||
|
<bit-menu #overflowMenu>
|
||||||
|
<ng-container *ngFor="let breadcrumb of overflow">
|
||||||
|
<ng-container *ngIf="breadcrumb.route">
|
||||||
|
<a
|
||||||
|
bitMenuItem
|
||||||
|
linkType="primary"
|
||||||
|
[routerLink]="breadcrumb.route"
|
||||||
|
[queryParams]="breadcrumb.queryParams"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||||
|
</a>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!breadcrumb.route">
|
||||||
|
<button bitMenuItem linkType="primary" (click)="breadcrumb.onClick($event)">
|
||||||
|
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</bit-menu>
|
||||||
|
<i class="bwi bwi-angle-right tw-mx-1.5 tw-text-main"></i>
|
||||||
|
|
||||||
|
<ng-container *ngFor="let breadcrumb of afterOverflow; let last = last">
|
||||||
|
<ng-container *ngIf="breadcrumb.route">
|
||||||
|
<a
|
||||||
|
bitLink
|
||||||
|
linkType="primary"
|
||||||
|
class="tw-my-2 tw-inline-block"
|
||||||
|
[routerLink]="breadcrumb.route"
|
||||||
|
[queryParams]="breadcrumb.queryParams"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||||
|
</a>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!breadcrumb.route">
|
||||||
|
<button
|
||||||
|
bitLink
|
||||||
|
linkType="primary"
|
||||||
|
class="tw-my-2 tw-inline-block"
|
||||||
|
(click)="breadcrumb.onClick($event)"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="breadcrumb.content"></ng-container>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
<i *ngIf="!last" class="bwi bwi-angle-right tw-mx-1.5 tw-text-main"></i>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
39
libs/components/src/breadcrumbs/breadcrumbs.component.ts
Normal file
39
libs/components/src/breadcrumbs/breadcrumbs.component.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Component, ContentChildren, Input, QueryList } from "@angular/core";
|
||||||
|
|
||||||
|
import { BreadcrumbComponent } from "./breadcrumb.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-breadcrumbs",
|
||||||
|
templateUrl: "./breadcrumbs.component.html",
|
||||||
|
})
|
||||||
|
export class BreadcrumbsComponent {
|
||||||
|
@Input()
|
||||||
|
show = 3;
|
||||||
|
|
||||||
|
private breadcrumbs: BreadcrumbComponent[] = [];
|
||||||
|
|
||||||
|
@ContentChildren(BreadcrumbComponent)
|
||||||
|
protected set breadcrumbList(value: QueryList<BreadcrumbComponent>) {
|
||||||
|
this.breadcrumbs = value.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get beforeOverflow() {
|
||||||
|
if (this.hasOverflow) {
|
||||||
|
return this.breadcrumbs.slice(0, this.show - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get overflow() {
|
||||||
|
return this.breadcrumbs.slice(this.show - 1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get afterOverflow() {
|
||||||
|
return this.breadcrumbs.slice(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get hasOverflow() {
|
||||||
|
return this.breadcrumbs.length > this.show;
|
||||||
|
}
|
||||||
|
}
|
17
libs/components/src/breadcrumbs/breadcrumbs.module.ts
Normal file
17
libs/components/src/breadcrumbs/breadcrumbs.module.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
import { RouterModule } from "@angular/router";
|
||||||
|
|
||||||
|
import { IconButtonModule } from "../icon-button";
|
||||||
|
import { LinkModule } from "../link";
|
||||||
|
import { MenuModule } from "../menu";
|
||||||
|
|
||||||
|
import { BreadcrumbComponent } from "./breadcrumb.component";
|
||||||
|
import { BreadcrumbsComponent } from "./breadcrumbs.component";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [CommonModule, LinkModule, IconButtonModule, MenuModule, RouterModule],
|
||||||
|
declarations: [BreadcrumbsComponent, BreadcrumbComponent],
|
||||||
|
exports: [BreadcrumbsComponent, BreadcrumbComponent],
|
||||||
|
})
|
||||||
|
export class BreadcrumbsModule {}
|
91
libs/components/src/breadcrumbs/breadcrumbs.stories.ts
Normal file
91
libs/components/src/breadcrumbs/breadcrumbs.stories.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { Component } from "@angular/core";
|
||||||
|
import { RouterModule } from "@angular/router";
|
||||||
|
import { Meta, Story, moduleMetadata } from "@storybook/angular";
|
||||||
|
|
||||||
|
import { IconButtonModule } from "../icon-button";
|
||||||
|
import { LinkModule } from "../link";
|
||||||
|
import { MenuModule } from "../menu";
|
||||||
|
|
||||||
|
import { BreadcrumbComponent } from "./breadcrumb.component";
|
||||||
|
import { BreadcrumbsComponent } from "./breadcrumbs.component";
|
||||||
|
|
||||||
|
interface Breadcrumb {
|
||||||
|
icon?: string;
|
||||||
|
name: string;
|
||||||
|
route: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
template: "",
|
||||||
|
})
|
||||||
|
class EmptyComponent {}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Component Library/Breadcrumbs",
|
||||||
|
component: BreadcrumbsComponent,
|
||||||
|
decorators: [
|
||||||
|
moduleMetadata({
|
||||||
|
declarations: [BreadcrumbComponent],
|
||||||
|
imports: [
|
||||||
|
LinkModule,
|
||||||
|
MenuModule,
|
||||||
|
IconButtonModule,
|
||||||
|
RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
args: {
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
argTypes: {
|
||||||
|
breadcrumbs: {
|
||||||
|
table: { disable: true },
|
||||||
|
},
|
||||||
|
click: { action: "clicked" },
|
||||||
|
},
|
||||||
|
} as Meta;
|
||||||
|
|
||||||
|
const Template: Story<BreadcrumbsComponent> = (args: BreadcrumbsComponent) => ({
|
||||||
|
props: args,
|
||||||
|
template: `
|
||||||
|
<h3 class="tw-text-main">Router links</h3>
|
||||||
|
<p>
|
||||||
|
<bit-breadcrumbs [show]="show">
|
||||||
|
<bit-breadcrumb *ngFor="let item of items" [icon]="item.icon" [route]="[item.route]">{{item.name}}</bit-breadcrumb>
|
||||||
|
</bit-breadcrumbs>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 class="tw-text-main">Click emit</h3>
|
||||||
|
<p>
|
||||||
|
<bit-breadcrumbs [show]="show">
|
||||||
|
<bit-breadcrumb *ngFor="let item of items" [icon]="item.icon" (click)="click($event)">{{item.name}}</bit-breadcrumb>
|
||||||
|
</bit-breadcrumbs>
|
||||||
|
</p>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TopLevel = Template.bind({});
|
||||||
|
TopLevel.args = {
|
||||||
|
items: [{ icon: "bwi-star", name: "Top Level" }] as Breadcrumb[],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SecondLevel = Template.bind({});
|
||||||
|
SecondLevel.args = {
|
||||||
|
items: [
|
||||||
|
{ name: "Acme Vault", route: "/" },
|
||||||
|
{ icon: "bwi-collection", name: "Collection", route: "collection" },
|
||||||
|
] as Breadcrumb[],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Overflow = Template.bind({});
|
||||||
|
Overflow.args = {
|
||||||
|
items: [
|
||||||
|
{ name: "Acme Vault", route: "" },
|
||||||
|
{ icon: "bwi-collection", name: "Collection", route: "collection" },
|
||||||
|
{ icon: "bwi-collection", name: "Middle-Collection 1", route: "middle-collection-1" },
|
||||||
|
{ icon: "bwi-collection", name: "Middle-Collection 2", route: "middle-collection-2" },
|
||||||
|
{ icon: "bwi-collection", name: "Middle-Collection 3", route: "middle-collection-3" },
|
||||||
|
{ icon: "bwi-collection", name: "Middle-Collection 4", route: "middle-collection-4" },
|
||||||
|
{ icon: "bwi-collection", name: "End Collection", route: "end-collection" },
|
||||||
|
] as Breadcrumb[],
|
||||||
|
};
|
3
libs/components/src/breadcrumbs/index.ts
Normal file
3
libs/components/src/breadcrumbs/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from "./breadcrumbs.module";
|
||||||
|
export * from "./breadcrumbs.component";
|
||||||
|
export * from "./breadcrumb.component";
|
@ -3,6 +3,7 @@ export * from "./avatar";
|
|||||||
export * from "./badge";
|
export * from "./badge";
|
||||||
export * from "./banner";
|
export * from "./banner";
|
||||||
export * from "./button";
|
export * from "./button";
|
||||||
|
export * from "./breadcrumbs";
|
||||||
export * from "./callout";
|
export * from "./callout";
|
||||||
export * from "./checkbox";
|
export * from "./checkbox";
|
||||||
export * from "./color-password";
|
export * from "./color-password";
|
||||||
|
Loading…
Reference in New Issue
Block a user