mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
[CL-17] Tabs - Router (#2952)
* [CL-17] Tabs - Routing * Updated titles * Revision changes * Replaced testing module to achieve active default state * Z-index for tab vs disabled * Revision changes * Updated z index on focus * Fixed background color of selected tab * Force text colors in-case bootstrap tries to override * Remove unecessary css rules, fix tabs moving when active Co-authored-by: Hinton <hinton@users.noreply.github.com>
This commit is contained in:
@@ -6,4 +6,5 @@ export * from "./callout";
|
|||||||
export * from "./form-field";
|
export * from "./form-field";
|
||||||
export * from "./menu";
|
export * from "./menu";
|
||||||
export * from "./utils/i18n-mock.service";
|
export * from "./utils/i18n-mock.service";
|
||||||
|
export * from "./tabs";
|
||||||
export * from "./submit-button";
|
export * from "./submit-button";
|
||||||
|
|||||||
3
libs/components/src/tabs/index.ts
Normal file
3
libs/components/src/tabs/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./tabs.module";
|
||||||
|
export * from "./tab-group.component";
|
||||||
|
export * from "./tab-item.component";
|
||||||
6
libs/components/src/tabs/tab-group.component.html
Normal file
6
libs/components/src/tabs/tab-group.component.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div
|
||||||
|
role="tablist"
|
||||||
|
class="tw-inline-flex tw-flex-wrap tw-leading-5 tw-border-0 tw-border-b tw-border-solid tw-border-secondary-300"
|
||||||
|
>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</div>
|
||||||
7
libs/components/src/tabs/tab-group.component.ts
Normal file
7
libs/components/src/tabs/tab-group.component.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-tab-group",
|
||||||
|
templateUrl: "./tab-group.component.html",
|
||||||
|
})
|
||||||
|
export class TabGroupComponent {}
|
||||||
26
libs/components/src/tabs/tab-item.component.html
Normal file
26
libs/components/src/tabs/tab-item.component.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<ng-container [ngSwitch]="disabled">
|
||||||
|
<a
|
||||||
|
*ngSwitchCase="false"
|
||||||
|
role="tab"
|
||||||
|
[class]="baseClassList"
|
||||||
|
[routerLink]="route"
|
||||||
|
[routerLinkActive]="activeClassList"
|
||||||
|
#rla="routerLinkActive"
|
||||||
|
[attr.aria-selected]="rla.isActive"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="content"></ng-container>
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
*ngSwitchCase="true"
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
[class]="baseClassList"
|
||||||
|
disabled
|
||||||
|
aria-disabled="true"
|
||||||
|
>
|
||||||
|
<ng-container [ngTemplateOutlet]="content"></ng-container>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #content>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</ng-template>
|
||||||
54
libs/components/src/tabs/tab-item.component.ts
Normal file
54
libs/components/src/tabs/tab-item.component.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { Component, Input } from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-tab-item",
|
||||||
|
templateUrl: "./tab-item.component.html",
|
||||||
|
})
|
||||||
|
export class TabItemComponent {
|
||||||
|
@Input() route: string; // ['/route']
|
||||||
|
@Input() disabled = false;
|
||||||
|
|
||||||
|
get baseClassList(): string[] {
|
||||||
|
return [
|
||||||
|
"tw-block",
|
||||||
|
"tw-relative",
|
||||||
|
"tw-py-2",
|
||||||
|
"tw-px-4",
|
||||||
|
"tw-font-semibold",
|
||||||
|
"tw-transition",
|
||||||
|
"tw-rounded-t",
|
||||||
|
"tw-border-0",
|
||||||
|
"tw-border-x",
|
||||||
|
"tw-border-t-4",
|
||||||
|
"tw-border-transparent",
|
||||||
|
"tw-border-solid",
|
||||||
|
"!tw-text-main",
|
||||||
|
"hover:tw-underline",
|
||||||
|
"hover:!tw-text-main",
|
||||||
|
"focus:tw-z-10",
|
||||||
|
"focus:tw-outline-none",
|
||||||
|
"focus:tw-ring-2",
|
||||||
|
"focus:tw-ring-primary-700",
|
||||||
|
"disabled:tw-bg-secondary-100",
|
||||||
|
"disabled:!tw-text-muted",
|
||||||
|
"disabled:tw-no-underline",
|
||||||
|
"disabled:tw-cursor-not-allowed",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get activeClassList(): string {
|
||||||
|
return [
|
||||||
|
"tw--mb-px",
|
||||||
|
"tw-border-x-secondary-300",
|
||||||
|
"tw-border-t-primary-500",
|
||||||
|
"tw-border-b",
|
||||||
|
"tw-border-b-background",
|
||||||
|
"tw-bg-background",
|
||||||
|
"!tw-text-primary-500",
|
||||||
|
"hover:tw-border-t-primary-700",
|
||||||
|
"hover:!tw-text-primary-700",
|
||||||
|
"focus:tw-border-t-primary-700",
|
||||||
|
"focus:!tw-text-primary-700",
|
||||||
|
].join(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
13
libs/components/src/tabs/tabs.module.ts
Normal file
13
libs/components/src/tabs/tabs.module.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
import { RouterModule } from "@angular/router";
|
||||||
|
|
||||||
|
import { TabGroupComponent } from "./tab-group.component";
|
||||||
|
import { TabItemComponent } from "./tab-item.component";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [CommonModule, RouterModule],
|
||||||
|
exports: [TabGroupComponent, TabItemComponent],
|
||||||
|
declarations: [TabGroupComponent, TabItemComponent],
|
||||||
|
})
|
||||||
|
export class TabsModule {}
|
||||||
84
libs/components/src/tabs/tabs.stories.ts
Normal file
84
libs/components/src/tabs/tabs.stories.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component } from "@angular/core";
|
||||||
|
import { RouterModule } from "@angular/router";
|
||||||
|
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||||
|
|
||||||
|
import { TabGroupComponent } from "./tab-group.component";
|
||||||
|
import { TabItemComponent } from "./tab-item.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-tab-active-dummy",
|
||||||
|
template: "Router - Active selected",
|
||||||
|
})
|
||||||
|
class ActiveDummyComponent {}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-tab-item-2-dummy",
|
||||||
|
template: "Router - Item 2 selected",
|
||||||
|
})
|
||||||
|
class ItemTwoDummyComponent {}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-tab-item-3-dummy",
|
||||||
|
template: "Router - Item 3 selected",
|
||||||
|
})
|
||||||
|
class ItemThreeDummyComponent {}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-tab-disabled-dummy",
|
||||||
|
template: "Router - Disabled selected",
|
||||||
|
})
|
||||||
|
class DisabledDummyComponent {}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Component Library/Tabs",
|
||||||
|
component: TabGroupComponent,
|
||||||
|
decorators: [
|
||||||
|
moduleMetadata({
|
||||||
|
declarations: [
|
||||||
|
TabGroupComponent,
|
||||||
|
TabItemComponent,
|
||||||
|
ActiveDummyComponent,
|
||||||
|
ItemTwoDummyComponent,
|
||||||
|
ItemThreeDummyComponent,
|
||||||
|
DisabledDummyComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
RouterModule.forRoot(
|
||||||
|
[
|
||||||
|
{ path: "", redirectTo: "active", pathMatch: "full" },
|
||||||
|
{ path: "active", component: ActiveDummyComponent },
|
||||||
|
{ path: "item-2", component: ItemTwoDummyComponent },
|
||||||
|
{ path: "item-3", component: ItemThreeDummyComponent },
|
||||||
|
{ path: "disabled", component: DisabledDummyComponent },
|
||||||
|
],
|
||||||
|
{ useHash: true }
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
parameters: {
|
||||||
|
design: {
|
||||||
|
type: "figma",
|
||||||
|
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=1881%3A17922",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as Meta;
|
||||||
|
|
||||||
|
const TabGroupTemplate: Story<TabGroupComponent> = (args: TabGroupComponent) => ({
|
||||||
|
props: args,
|
||||||
|
template: `
|
||||||
|
<bit-tab-group>
|
||||||
|
<bit-tab-item [route]="['active']">Active</bit-tab-item>
|
||||||
|
<bit-tab-item [route]="['item-2']">Item 2</bit-tab-item>
|
||||||
|
<bit-tab-item [route]="['item-3']">Item 3</bit-tab-item>
|
||||||
|
<bit-tab-item [route]="['disabled']" [disabled]="true">Disabled</bit-tab-item>
|
||||||
|
</bit-tab-group>
|
||||||
|
<div class="tw-bg-transparent tw-text-semibold tw-text-center !tw-text-main tw-py-10">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TabGroup = TabGroupTemplate.bind({});
|
||||||
@@ -60,6 +60,8 @@ module.exports = {
|
|||||||
info: "var(--color-info-500)",
|
info: "var(--color-info-500)",
|
||||||
primary: {
|
primary: {
|
||||||
300: "var(--color-primary-300)",
|
300: "var(--color-primary-300)",
|
||||||
|
500: "var(--color-primary-500)",
|
||||||
|
700: "var(--color-primary-700)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ringOffsetColor: ({ theme }) => ({
|
ringOffsetColor: ({ theme }) => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user