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]="''">
|
<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'">
|
<a bitLink [routerLink]="'/at-risk-passwords'">
|
||||||
{{
|
{{
|
||||||
(taskCount === 1 ? "reviewAndChangeAtRiskPassword" : "reviewAndChangeAtRiskPasswordsPlural")
|
(taskCount === 1 ? "reviewAndChangeAtRiskPassword" : "reviewAndChangeAtRiskPasswordsPlural")
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
<aside
|
<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"
|
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()"
|
[ngClass]="[calloutClass()]"
|
||||||
[attr.aria-labelledby]="titleId"
|
[attr.aria-labelledby]="titleId"
|
||||||
>
|
>
|
||||||
@if (titleComputed(); as title) {
|
@let title = titleComputed();
|
||||||
<header
|
@let icon = iconComputed();
|
||||||
id="{{ titleId }}"
|
|
||||||
class="tw-mb-1 tw-mt-0 tw-text-base tw-font-semibold tw-flex tw-gap-2 tw-items-start"
|
@if (icon) {
|
||||||
>
|
|
||||||
@if (iconComputed(); as icon) {
|
|
||||||
<i
|
<i
|
||||||
class="bwi !tw-text-main tw-relative tw-top-[3px]"
|
class="bwi tw-relative"
|
||||||
[ngClass]="[icon]"
|
[ngClass]="[icon, title ? 'tw-top-[3px] tw-self-start' : 'tw-top-[1px]']"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
}
|
}
|
||||||
|
<div class="tw-flex tw-flex-col tw-gap-0.5">
|
||||||
|
@if (title) {
|
||||||
|
<header id="{{ titleId }}" class="tw-text-base tw-font-semibold">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</header>
|
</header>
|
||||||
}
|
}
|
||||||
<div class="tw-ps-6" bitTypography="body2">
|
<div bitTypography="body2">
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -56,5 +56,12 @@ describe("Callout", () => {
|
|||||||
expect(component.titleComputed()).toBe("Error");
|
expect(component.titleComputed()).toBe("Error");
|
||||||
expect(component.iconComputed()).toBe("bwi-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 { SharedModule } from "../shared";
|
||||||
import { TypographyModule } from "../typography";
|
import { TypographyModule } from "../typography";
|
||||||
|
|
||||||
export type CalloutTypes = "success" | "info" | "warning" | "danger";
|
export type CalloutTypes = "success" | "info" | "warning" | "danger" | "default";
|
||||||
|
|
||||||
const defaultIcon: Record<CalloutTypes, string> = {
|
const defaultIcon: Record<CalloutTypes, string> = {
|
||||||
success: "bwi-check-circle",
|
success: "bwi-check-circle",
|
||||||
info: "bwi-info-circle",
|
info: "bwi-info-circle",
|
||||||
warning: "bwi-exclamation-triangle",
|
warning: "bwi-exclamation-triangle",
|
||||||
danger: "bwi-error",
|
danger: "bwi-error",
|
||||||
|
default: "bwi-star",
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultI18n: Partial<Record<CalloutTypes, string>> = {
|
const defaultI18n: Partial<Record<CalloutTypes, string>> = {
|
||||||
@@ -55,13 +56,15 @@ export class CalloutComponent {
|
|||||||
protected readonly calloutClass = computed(() => {
|
protected readonly calloutClass = computed(() => {
|
||||||
switch (this.type()) {
|
switch (this.type()) {
|
||||||
case "danger":
|
case "danger":
|
||||||
return "tw-bg-danger-100";
|
return "tw-bg-danger-100 tw-border-danger-700 tw-text-danger-700";
|
||||||
case "info":
|
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":
|
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":
|
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} />
|
<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
|
### Warning
|
||||||
|
|
||||||
Use a warning callout if the user is about to perform an action that may have unintended or
|
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
|
the content is static, do not use the alert role. This will cause a screen reader to announce the
|
||||||
callout content on page load.
|
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 { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
|
||||||
|
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
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 { formatArgsForCodeSnippet } from "../../../../.storybook/format-args-for-code-snippet";
|
||||||
import { I18nMockService } from "../utils/i18n-mock.service";
|
import { I18nMockService } from "../utils/i18n-mock.service";
|
||||||
@@ -12,6 +13,7 @@ export default {
|
|||||||
component: CalloutComponent,
|
component: CalloutComponent,
|
||||||
decorators: [
|
decorators: [
|
||||||
moduleMetadata({
|
moduleMetadata({
|
||||||
|
imports: [LinkModule, IconModule],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: I18nService,
|
provide: I18nService,
|
||||||
@@ -69,6 +71,14 @@ export const Danger: Story = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
...Info,
|
||||||
|
args: {
|
||||||
|
...Info.args,
|
||||||
|
type: "default",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const CustomIcon: Story = {
|
export const CustomIcon: Story = {
|
||||||
...Info,
|
...Info,
|
||||||
args: {
|
args: {
|
||||||
@@ -80,6 +90,35 @@ export const CustomIcon: Story = {
|
|||||||
export const NoTitle: Story = {
|
export const NoTitle: Story = {
|
||||||
...Info,
|
...Info,
|
||||||
args: {
|
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>
|
||||||
|
|
||||||
<bit-callout *ngIf="hasLoginUri && hadPendingChangePasswordTask" type="warning" [title]="''">
|
<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()">
|
<a bitLink href="#" appStopClick (click)="launchChangePassword()">
|
||||||
{{ "changeAtRiskPassword" | i18n }}
|
{{ "changeAtRiskPassword" | i18n }}
|
||||||
<i class="bwi bwi-external-link tw-ml-1" aria-hidden="true"></i>
|
<i class="bwi bwi-external-link tw-ml-1" aria-hidden="true"></i>
|
||||||
|
|||||||
Reference in New Issue
Block a user