1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-13 06:54:07 +00:00

[CL-230] [CL-296] Update button styles (#9345)

Co-authored-by: Will Martin <contact@willmartian.com>
This commit is contained in:
Victoria League
2024-05-28 15:00:58 -04:00
committed by GitHub
parent 537a5b93f3
commit 42a98bc6b4
5 changed files with 52 additions and 82 deletions

View File

@@ -27,57 +27,6 @@ describe("Button", () => {
linkDebugElement = fixture.debugElement.query(By.css("a"));
}));
it("should apply classes based on type", () => {
testAppComponent.buttonType = "primary";
fixture.detectChanges();
expect(buttonDebugElement.nativeElement.classList.contains("tw-bg-primary-600")).toBe(true);
expect(linkDebugElement.nativeElement.classList.contains("tw-bg-primary-600")).toBe(true);
testAppComponent.buttonType = "secondary";
fixture.detectChanges();
expect(buttonDebugElement.nativeElement.classList.contains("tw-border-text-muted")).toBe(true);
expect(linkDebugElement.nativeElement.classList.contains("tw-border-text-muted")).toBe(true);
testAppComponent.buttonType = "danger";
fixture.detectChanges();
expect(buttonDebugElement.nativeElement.classList.contains("tw-border-danger-600")).toBe(true);
expect(linkDebugElement.nativeElement.classList.contains("tw-border-danger-600")).toBe(true);
testAppComponent.buttonType = "unstyled";
fixture.detectChanges();
expect(
Array.from(buttonDebugElement.nativeElement.classList).some((klass: string) =>
klass.startsWith("tw-bg"),
),
).toBe(false);
expect(
Array.from(linkDebugElement.nativeElement.classList).some((klass: string) =>
klass.startsWith("tw-bg"),
),
).toBe(false);
testAppComponent.buttonType = null;
fixture.detectChanges();
expect(buttonDebugElement.nativeElement.classList.contains("tw-border-text-muted")).toBe(true);
expect(linkDebugElement.nativeElement.classList.contains("tw-border-text-muted")).toBe(true);
});
it("should apply block when true and inline-block when false", () => {
testAppComponent.block = true;
fixture.detectChanges();
expect(buttonDebugElement.nativeElement.classList.contains("tw-block")).toBe(true);
expect(linkDebugElement.nativeElement.classList.contains("tw-block")).toBe(true);
expect(buttonDebugElement.nativeElement.classList.contains("tw-inline-block")).toBe(false);
expect(linkDebugElement.nativeElement.classList.contains("tw-inline-block")).toBe(false);
testAppComponent.block = false;
fixture.detectChanges();
expect(buttonDebugElement.nativeElement.classList.contains("tw-inline-block")).toBe(true);
expect(linkDebugElement.nativeElement.classList.contains("tw-inline-block")).toBe(true);
expect(buttonDebugElement.nativeElement.classList.contains("tw-block")).toBe(false);
expect(linkDebugElement.nativeElement.classList.contains("tw-block")).toBe(false);
});
it("should not be disabled when loading and disabled are false", () => {
testAppComponent.loading = false;
testAppComponent.disabled = false;

View File

@@ -6,7 +6,7 @@ import { ButtonLikeAbstraction, ButtonType } from "../shared/button-like.abstrac
const focusRing = [
"focus-visible:tw-ring",
"focus-visible:tw-ring-offset-2",
"focus-visible:tw-ring-primary-700",
"focus-visible:tw-ring-primary-500",
"focus-visible:tw-z-10",
];
@@ -17,37 +17,24 @@ const buttonStyles: Record<ButtonType, string[]> = {
"!tw-text-contrast",
"hover:tw-bg-primary-700",
"hover:tw-border-primary-700",
"disabled:tw-bg-primary-600/60",
"disabled:tw-border-primary-600/60",
"disabled:!tw-text-contrast/60",
"disabled:tw-bg-clip-padding",
"disabled:tw-cursor-not-allowed",
...focusRing,
],
secondary: [
"tw-bg-transparent",
"tw-border-text-muted",
"!tw-text-muted",
"hover:tw-bg-text-muted",
"hover:tw-border-text-muted",
"hover:!tw-text-contrast",
"disabled:tw-bg-transparent",
"disabled:tw-border-text-muted/60",
"disabled:!tw-text-muted/60",
"disabled:tw-cursor-not-allowed",
"tw-border-primary-600",
"!tw-text-primary-600",
"hover:tw-bg-transparent",
"hover:tw-border-primary-700",
"hover:!tw-text-primary-700",
...focusRing,
],
danger: [
"tw-bg-transparent",
"tw-border-danger-600",
"!tw-text-danger",
"hover:tw-bg-danger-600",
"hover:tw-border-danger-600",
"hover:!tw-text-contrast",
"disabled:tw-bg-transparent",
"disabled:tw-border-danger-600/60",
"disabled:!tw-text-danger/60",
"disabled:tw-cursor-not-allowed",
"hover:tw-bg-transparent",
"hover:tw-border-danger-700",
"hover:!tw-text-danger-700",
...focusRing,
],
unstyled: [],
@@ -64,14 +51,22 @@ export class ButtonComponent implements ButtonLikeAbstraction {
"tw-font-semibold",
"tw-py-1.5",
"tw-px-3",
"tw-rounded",
"tw-rounded-full",
"tw-transition",
"tw-border",
"tw-border-2",
"tw-border-solid",
"tw-text-center",
"tw-no-underline",
"hover:tw-no-underline",
"hover:tw-underline",
"focus:tw-outline-none",
"disabled:tw-bg-secondary-300",
"disabled:hover:tw-bg-secondary-300",
"disabled:tw-border-secondary-300",
"disabled:hover:tw-border-secondary-300",
"disabled:!tw-text-muted",
"disabled:hover:!tw-text-muted",
"disabled:tw-cursor-not-allowed",
"disabled:hover:tw-no-underline",
]
.concat(this.block ? ["tw-w-full", "tw-block"] : ["tw-inline-block"])
.concat(buttonStyles[this.buttonType ?? "secondary"]);

View File

@@ -60,9 +60,6 @@ Use the danger styling only in settings when the user may preform a permanent ac
## Disabled UI
Both the disabled and loading states use the default states color with a 60% opacity or
`tw-opacity-60`.
<Story of={stories.Disabled} />
## Block

View File

@@ -23,9 +23,21 @@ type Story = StoryObj<ButtonComponent>;
export const Primary: Story = {
render: (args) => ({
props: args,
template: `
template: /*html*/ `
<div class="tw-flex tw-gap-4 tw-mb-6">
<button bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block">Button</button>
<a bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" href="#" class="tw-ml-2">Link</a>
<button bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-hover">Button:hover</button>
<button bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-focus-visible">Button:focus-visible</button>
<button bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-hover tw-test-focus-visible">Button:hover:focus-visible</button>
<button bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-active">Button:active</button>
</div>
<div class="tw-flex tw-gap-4">
<a href="#" bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block">Anchor</a>
<a href="#" bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-hover">Anchor:hover</a>
<a href="#" bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-focus-visible">Anchor:focus-visible</a>
<a href="#" bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-hover tw-test-focus-visible">Anchor:hover:focus-visible</a>
<a href="#" bitButton [disabled]="disabled" [loading]="loading" [buttonType]="buttonType" [block]="block" class="tw-test-active">Anchor:active</a>
</div>
`,
}),
args: {

View File

@@ -77,7 +77,11 @@ module.exports = {
alt2: rgba("--color-text-alt2"),
code: rgba("--color-text-code"),
success: rgba("--color-success-600"),
danger: rgba("--color-danger-600"),
danger: {
DEFAULT: rgba("--color-danger-600"),
600: rgba("--color-danger-600"),
700: rgba("--color-danger-700"),
},
warning: rgba("--color-warning-600"),
info: rgba("--color-info-600"),
primary: {
@@ -124,5 +128,18 @@ module.exports = {
{},
);
}),
plugin(function ({ addVariant }) {
for (const state of [
"active",
"hover",
"focus",
"focus-within",
"focus-visible",
"target",
"visited",
]) {
addVariant(state, [`&:${state}`, `&.test-${state}`]);
}
}),
],
};