1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-20 03:13:55 +00:00
Files
browser/libs/components/src/berry/berry.component.ts
Leslie Xiong 03875dcf05 [CL-1022] Update Berry Styles (#18799)
* created 'berry' component

* added 'bit-berry' to 'popup-tab-navigation'

* simplified - removed null checks

* changed 'effectiveSize' to 'computedSize'

* fixed 'accentPrimary' color

* updated to not render berry if 'count' is 0 or negative number

* simplified checking count undefined

* updated computed padding

* switched from `[ngClass]` to `[class]`

* updated 'popup-tab-navigation' berry to use 'danger' variant

* fixed berry positioning in popup-tab-navigation

* updated content logic

* cleanup unused 'ngClass'

* updated conditional rendering of berry

* updated story 'Usage'

* updates with adding berry 'type'

* added type "status" to popup-tab-navigation

* fixed type error

* updated 'Count Behavior' description
2026-02-17 09:52:15 -08:00

81 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ChangeDetectionStrategy, Component, computed, input } from "@angular/core";
export type BerryVariant =
| "primary"
| "subtle"
| "success"
| "warning"
| "danger"
| "accentPrimary"
| "contrast";
/**
* The berry component is a compact visual indicator used to display short,
* supplemental status information about another element,
* like a navigation item, button, or icon button.
* They draw users attention to status changes or new notifications.
*
* > `NOTE:` The maximum displayed value is 999. If the value is over 999, a “+” character is appended to indicate more.
*/
@Component({
selector: "bit-berry",
templateUrl: "berry.component.html",
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BerryComponent {
protected readonly variant = input<BerryVariant>("primary");
protected readonly value = input<number>();
protected readonly type = input<"status" | "count">("count");
protected readonly content = computed(() => {
const value = this.value();
const type = this.type();
if (type === "status" || !value || value < 0) {
return undefined;
}
return value > 999 ? "999+" : `${value}`;
});
protected readonly textColor = computed(() => {
return this.variant() === "contrast" ? "tw-text-fg-dark" : "tw-text-fg-white";
});
protected readonly padding = computed(() => {
return (this.value()?.toString().length ?? 0) > 2 ? "tw-px-1.5 tw-py-0.5" : "";
});
protected readonly containerClasses = computed(() => {
const baseClasses = [
"tw-inline-flex",
"tw-items-center",
"tw-justify-center",
"tw-align-middle",
"tw-text-xxs",
"tw-rounded-full",
];
const typeClasses = {
status: ["tw-h-2", "tw-w-2"],
count: ["tw-h-4", "tw-min-w-4", this.padding()],
};
const variantClass = {
primary: "tw-bg-bg-brand",
subtle: "tw-bg-bg-contrast",
success: "tw-bg-bg-success",
warning: "tw-bg-bg-warning",
danger: "tw-bg-bg-danger",
accentPrimary: "tw-bg-fg-accent-primary-strong",
contrast: "tw-bg-bg-white",
};
return [
...baseClasses,
...typeClasses[this.type()],
variantClass[this.variant()],
this.textColor(),
].join(" ");
});
}