mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 13:53:34 +00:00
[CL-866] Add default callout and update styles (#16481)
* Updated callout styles * Added default callout variant * Refactored component to support icon + content variants (with no header) --------- Co-authored-by: Vicki League <vleague@bitwarden.com> Co-authored-by: Bryan Cunningham <bryan.cunningham@me.com>
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<bit-callout *ngIf="(pendingTasks$ | async)?.length as taskCount" type="warning" [title]="''">
|
||||
<i class="bwi bwi-exclamation-triangle tw-text-warning" aria-hidden="true"></i>
|
||||
<a bitLink [routerLink]="'/at-risk-passwords'">
|
||||
{{
|
||||
(taskCount === 1 ? "reviewAndChangeAtRiskPassword" : "reviewAndChangeAtRiskPasswordsPlural")
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
<aside
|
||||
class="tw-mb-4 tw-box-border tw-rounded-lg tw-bg-background tw-ps-3 tw-pe-3 tw-py-2 tw-leading-5 tw-text-main"
|
||||
[ngClass]="calloutClass()"
|
||||
class="tw-mb-4 tw-box-border tw-border tw-border-solid tw-rounded-lg tw-bg-background tw-ps-4 tw-pe-4 tw-py-3 tw-leading-5 tw-flex tw-gap-2"
|
||||
[ngClass]="[calloutClass()]"
|
||||
[attr.aria-labelledby]="titleId"
|
||||
>
|
||||
@if (titleComputed(); as title) {
|
||||
<header
|
||||
id="{{ titleId }}"
|
||||
class="tw-mb-1 tw-mt-0 tw-text-base tw-font-semibold tw-flex tw-gap-2 tw-items-start"
|
||||
>
|
||||
@if (iconComputed(); as icon) {
|
||||
<i
|
||||
class="bwi !tw-text-main tw-relative tw-top-[3px]"
|
||||
[ngClass]="[icon]"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
}
|
||||
{{ title }}
|
||||
</header>
|
||||
@let title = titleComputed();
|
||||
@let icon = iconComputed();
|
||||
|
||||
@if (icon) {
|
||||
<i
|
||||
class="bwi tw-relative"
|
||||
[ngClass]="[icon, title ? 'tw-top-[3px] tw-self-start' : 'tw-top-[1px]']"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
}
|
||||
<div class="tw-ps-6" bitTypography="body2">
|
||||
<ng-content></ng-content>
|
||||
<div class="tw-flex tw-flex-col tw-gap-0.5">
|
||||
@if (title) {
|
||||
<header id="{{ titleId }}" class="tw-text-base tw-font-semibold">
|
||||
{{ title }}
|
||||
</header>
|
||||
}
|
||||
<div bitTypography="body2">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -56,5 +56,12 @@ describe("Callout", () => {
|
||||
expect(component.titleComputed()).toBe("Error");
|
||||
expect(component.iconComputed()).toBe("bwi-error");
|
||||
});
|
||||
|
||||
it("default", () => {
|
||||
fixture.componentRef.setInput("type", "default");
|
||||
fixture.detectChanges();
|
||||
expect(component.titleComputed()).toBeUndefined();
|
||||
expect(component.iconComputed()).toBe("bwi-star");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,13 +5,14 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { SharedModule } from "../shared";
|
||||
import { TypographyModule } from "../typography";
|
||||
|
||||
export type CalloutTypes = "success" | "info" | "warning" | "danger";
|
||||
export type CalloutTypes = "success" | "info" | "warning" | "danger" | "default";
|
||||
|
||||
const defaultIcon: Record<CalloutTypes, string> = {
|
||||
success: "bwi-check-circle",
|
||||
info: "bwi-info-circle",
|
||||
warning: "bwi-exclamation-triangle",
|
||||
danger: "bwi-error",
|
||||
default: "bwi-star",
|
||||
};
|
||||
|
||||
const defaultI18n: Partial<Record<CalloutTypes, string>> = {
|
||||
@@ -55,13 +56,15 @@ export class CalloutComponent {
|
||||
protected readonly calloutClass = computed(() => {
|
||||
switch (this.type()) {
|
||||
case "danger":
|
||||
return "tw-bg-danger-100";
|
||||
return "tw-bg-danger-100 tw-border-danger-700 tw-text-danger-700";
|
||||
case "info":
|
||||
return "tw-bg-info-100";
|
||||
return "tw-bg-info-100 tw-bg-info-100 tw-border-info-700 tw-text-info-700";
|
||||
case "success":
|
||||
return "tw-bg-success-100";
|
||||
return "tw-bg-success-100 tw-bg-success-100 tw-border-success-700 tw-text-success-700";
|
||||
case "warning":
|
||||
return "tw-bg-warning-100";
|
||||
return "tw-bg-warning-100 tw-bg-warning-100 tw-border-warning-700 tw-text-warning-700";
|
||||
case "default":
|
||||
return "tw-bg-background-alt tw-border-secondary-700 tw-text-secondary-700";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,6 +41,12 @@ automatically be checked.
|
||||
|
||||
<Canvas of={stories.Info} />
|
||||
|
||||
### Default
|
||||
|
||||
Use for similar cases as the info callout but when content does not need to be as prominent.
|
||||
|
||||
<Canvas of={stories.Default} />
|
||||
|
||||
### Warning
|
||||
|
||||
Use a warning callout if the user is about to perform an action that may have unintended or
|
||||
@@ -67,4 +73,8 @@ Use the `role=”alert”` only if the callout is appearing on a page after the
|
||||
the content is static, do not use the alert role. This will cause a screen reader to announce the
|
||||
callout content on page load.
|
||||
|
||||
Ensure the title's color contrast remains WCAG compliant with the callout's background.
|
||||
Ensure color contrast remains WCAG compliant with the callout's background. This is especially
|
||||
important when adding `bit-link` or `bit-button` to the content area since the callout background is
|
||||
colored. Currently only the `info` and `default` callouts are WCAG compliant for the `primary`
|
||||
styling of these elements. The `secondary` `bit-link` styling may be used with the remaining
|
||||
variants.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LinkModule, IconModule } from "@bitwarden/components";
|
||||
|
||||
import { formatArgsForCodeSnippet } from "../../../../.storybook/format-args-for-code-snippet";
|
||||
import { I18nMockService } from "../utils/i18n-mock.service";
|
||||
@@ -12,6 +13,7 @@ export default {
|
||||
component: CalloutComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [LinkModule, IconModule],
|
||||
providers: [
|
||||
{
|
||||
provide: I18nService,
|
||||
@@ -69,6 +71,14 @@ export const Danger: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const Default: Story = {
|
||||
...Info,
|
||||
args: {
|
||||
...Info.args,
|
||||
type: "default",
|
||||
},
|
||||
};
|
||||
|
||||
export const CustomIcon: Story = {
|
||||
...Info,
|
||||
args: {
|
||||
@@ -80,6 +90,35 @@ export const CustomIcon: Story = {
|
||||
export const NoTitle: Story = {
|
||||
...Info,
|
||||
args: {
|
||||
icon: "bwi-star",
|
||||
icon: "",
|
||||
},
|
||||
};
|
||||
|
||||
export const NoTitleWithIcon: Story = {
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-callout ${formatArgsForCodeSnippet<CalloutComponent>(args)}>The content of the callout</bit-callout>
|
||||
`,
|
||||
}),
|
||||
args: {
|
||||
type: "default",
|
||||
icon: "bwi-globe",
|
||||
},
|
||||
};
|
||||
|
||||
export const WithTextButton: Story = {
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-callout ${formatArgsForCodeSnippet<CalloutComponent>(args)}>
|
||||
<p class="tw-mb-2">The content of the callout</p>
|
||||
<a bitLink> Visit the help center<i aria-hidden="true" class="bwi bwi-fw bwi-sm bwi-angle-right"></i> </a>
|
||||
</bit-callout>
|
||||
`,
|
||||
}),
|
||||
args: {
|
||||
type: "default",
|
||||
icon: "",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
</bit-callout>
|
||||
|
||||
<bit-callout *ngIf="hasLoginUri && hadPendingChangePasswordTask" type="warning" [title]="''">
|
||||
<i class="bwi bwi-exclamation-triangle tw-text-warning" aria-hidden="true"></i>
|
||||
<a bitLink href="#" appStopClick (click)="launchChangePassword()">
|
||||
{{ "changeAtRiskPassword" | i18n }}
|
||||
<i class="bwi bwi-external-link tw-ml-1" aria-hidden="true"></i>
|
||||
|
||||
Reference in New Issue
Block a user