1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-28 10:33:31 +00:00

merge in main

This commit is contained in:
William Martin
2025-05-28 13:45:31 -04:00
1404 changed files with 33141 additions and 18131 deletions

View File

@@ -3,6 +3,7 @@ import { Component } from "@angular/core";
@Component({
selector: "app-root",
template: "",
standalone: false,
})
export class AppComponent {
title = "components";

View File

@@ -123,7 +123,7 @@ export class AvatarComponent implements OnChanges {
textTag.setAttribute("fill", Utils.pickTextColorBasedOnBgColor(color, 135, true));
textTag.setAttribute(
"font-family",
'"DM Sans","Helvetica Neue",Helvetica,Arial,' +
'Roboto,"Helvetica Neue",Helvetica,Arial,' +
'sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"',
);
// Warning do not use innerHTML here, characters are user provided

View File

@@ -14,7 +14,8 @@
<!-- Primary button -->
<button
type="button"
class="fvw-target tw-inline-flex tw-gap-1.5 tw-items-center tw-justify-between tw-bg-transparent hover:tw-bg-transparent tw-border-none tw-outline-none tw-w-full tw-py-1 tw-pl-3 last:tw-pr-3 [&:not(:last-child)]:tw-pr-0 tw-truncate tw-text-[color:inherit] tw-text-[length:inherit]"
class="tw-inline-flex tw-gap-1.5 tw-items-center tw-justify-between tw-bg-transparent hover:tw-bg-transparent tw-border-none tw-outline-none tw-w-full tw-py-1 tw-pl-3 last:tw-pr-3 [&:not(:last-child)]:tw-pr-0 tw-truncate tw-text-[color:inherit] tw-text-[length:inherit]"
data-fvw-target
[ngClass]="{
'tw-cursor-not-allowed': disabled,
'group-hover/chip-select:tw-text-secondary-700': !selectedOption && !disabled,

View File

@@ -80,7 +80,7 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
protected focusVisibleWithin = signal(false);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.focusVisibleWithin.set(target.matches(".fvw-target:focus-visible"));
this.focusVisibleWithin.set(target.matches("[data-fvw-target]:focus-visible"));
}
@HostListener("focusout")
onFocusOut() {

View File

@@ -2,6 +2,8 @@ import { Component, computed, HostBinding, input } from "@angular/core";
import { Utils } from "@bitwarden/common/platform/misc/utils";
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
enum CharacterType {
Letter,
Emoji,

View File

@@ -56,7 +56,8 @@
<ng-container *ngTemplateOutlet="prefixContent"></ng-container>
</div>
<div
class="default-content tw-w-full tw-relative tw-py-2 has-[bit-select]:tw-p-0 has-[bit-multi-select]:tw-p-0 has-[input:read-only:not([hidden])]:tw-bg-secondary-100 has-[textarea:read-only:not([hidden])]:tw-bg-secondary-100"
class="tw-w-full tw-relative tw-py-2 has-[bit-select]:tw-p-0 has-[bit-multi-select]:tw-p-0 has-[input:read-only:not([hidden])]:tw-bg-secondary-100 has-[textarea:read-only:not([hidden])]:tw-bg-secondary-100"
data-default-content
[ngClass]="[
prefixHasChildren() ? '' : 'tw-rounded-l-lg tw-pl-3',
suffixHasChildren() ? '' : 'tw-rounded-r-lg tw-pr-3',
@@ -96,7 +97,8 @@
<ng-container *ngTemplateOutlet="prefixContent"></ng-container>
</div>
<div
class="default-content tw-w-full tw-pb-0 tw-relative [&>*]:tw-p-0 [&>*::selection]:tw-bg-primary-700 [&>*::selection]:tw-text-contrast"
class="tw-w-full tw-pb-0 tw-relative [&>*]:tw-p-0 [&>*::selection]:tw-bg-primary-700 [&>*::selection]:tw-text-contrast"
data-default-content
>
<ng-container *ngTemplateOutlet="defaultContent"></ng-container>
</div>

View File

@@ -91,7 +91,7 @@ export class BitFormFieldComponent implements AfterContentChecked {
protected defaultContentIsFocused = signal(false);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.defaultContentIsFocused.set(target.matches(".default-content *:focus-visible"));
this.defaultContentIsFocused.set(target.matches("[data-default-content] *:focus-visible"));
}
@HostListener("focusout")
onFocusOut() {

View File

@@ -19,6 +19,7 @@ import { FocusableElement } from "../shared/focusable-element";
*/
@Directive({
selector: "[appAutofocus], [bitAutofocus]",
standalone: false,
})
export class AutofocusDirective implements AfterContentChecked {
@Input() set appAutofocus(condition: boolean | string) {

View File

@@ -25,7 +25,8 @@ import { TypographyModule } from "../typography";
* y-axis padding should be kept in sync with `item-action.component.ts`'s `top` and `bottom` units.
* we want this to be the same height as the `item-action`'s `:after` element
*/
"fvw-target tw-outline-none tw-text-main hover:tw-text-main tw-no-underline hover:tw-no-underline tw-text-base tw-py-2 tw-px-4 bit-compact:tw-py-1.5 bit-compact:tw-px-2 tw-bg-transparent tw-w-full tw-border-none tw-flex tw-gap-4 tw-items-center tw-justify-between",
"tw-outline-none tw-text-main hover:tw-text-main tw-no-underline hover:tw-no-underline tw-text-base tw-py-2 tw-px-4 bit-compact:tw-py-1.5 bit-compact:tw-px-2 tw-bg-transparent tw-w-full tw-border-none tw-flex tw-gap-4 tw-items-center tw-justify-between",
"data-fvw-target": "",
},
changeDetection: ChangeDetectionStrategy.OnPush,
})

View File

@@ -1,4 +1,4 @@
<bit-item-action class="item-main-content tw-flex tw-flex-1 tw-overflow-hidden">
<bit-item-action class="tw-flex tw-flex-1 tw-overflow-hidden" data-item-main-content>
<ng-content></ng-content>
</bit-item-action>

View File

@@ -23,7 +23,7 @@ import { ItemActionComponent } from "./item-action.component";
providers: [{ provide: A11yRowDirective, useExisting: ItemComponent }],
host: {
class:
"tw-block tw-box-border tw-overflow-hidden tw-flex tw-bg-background [&:has(.item-main-content_button:hover,.item-main-content_a:hover)]:tw-cursor-pointer [&:has(.item-main-content_button:hover,.item-main-content_a:hover)]:tw-bg-primary-100 tw-text-main tw-border-solid tw-border-b tw-border-0 [&:not(bit-layout_*)]:tw-rounded-lg bit-compact:[&:not(bit-layout_*)]:tw-rounded-none bit-compact:[&:not(bit-layout_*)]:last-of-type:tw-rounded-b-lg bit-compact:[&:not(bit-layout_*)]:first-of-type:tw-rounded-t-lg tw-min-h-9 tw-mb-1.5 bit-compact:tw-mb-0",
"tw-block tw-box-border tw-overflow-hidden tw-flex tw-bg-background [&:has([data-item-main-content]_button:hover,[data-item-main-content]_a:hover)]:tw-cursor-pointer [&:has([data-item-main-content]_button:hover,[data-item-main-content]_a:hover)]:tw-bg-primary-100 tw-text-main tw-border-solid tw-border-b tw-border-0 [&:not(bit-layout_*)]:tw-rounded-lg bit-compact:[&:not(bit-layout_*)]:tw-rounded-none bit-compact:[&:not(bit-layout_*)]:last-of-type:tw-rounded-b-lg bit-compact:[&:not(bit-layout_*)]:first-of-type:tw-rounded-t-lg tw-min-h-9 tw-mb-1.5 bit-compact:tw-mb-0",
},
})
export class ItemComponent extends A11yRowDirective {
@@ -33,7 +33,7 @@ export class ItemComponent extends A11yRowDirective {
protected focusVisibleWithin = signal(false);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.focusVisibleWithin.set(target.matches(".fvw-target:focus-visible"));
this.focusVisibleWithin.set(target.matches("[data-fvw-target]:focus-visible"));
}
@HostListener("focusout")
onFocusOut() {

View File

@@ -16,11 +16,7 @@ import { filter, mergeWith } from "rxjs/operators";
import { MenuComponent } from "./menu.component";
@Directive({
selector: "[bitMenuTriggerFor]",
exportAs: "menuTrigger",
standalone: true,
})
@Directive({ selector: "[bitMenuTriggerFor]", exportAs: "menuTrigger", standalone: true })
export class MenuTriggerForDirective implements OnDestroy {
@HostBinding("attr.aria-expanded") isOpen = false;
@HostBinding("attr.aria-haspopup") get hasPopup(): "menu" | "dialog" {
@@ -42,18 +38,10 @@ export class MenuTriggerForDirective implements OnDestroy {
.position()
.flexibleConnectedTo(this.elementRef)
.withPositions([
{
originX: "start",
originY: "bottom",
overlayX: "start",
overlayY: "top",
},
{
originX: "end",
originY: "bottom",
overlayX: "end",
overlayY: "top",
},
{ originX: "start", originY: "bottom", overlayX: "start", overlayY: "top" },
{ originX: "end", originY: "bottom", overlayX: "end", overlayY: "top" },
{ originX: "start", originY: "top", overlayX: "start", overlayY: "bottom" },
{ originX: "end", originY: "top", overlayX: "end", overlayY: "bottom" },
])
.withLockedPosition(true)
.withFlexibleDimensions(false)

View File

@@ -70,10 +70,11 @@
<!-- Show if a value was passed to `this.to` -->
<ng-template #isAnchor>
<!-- The `fvw` class passes focus to `this.focusVisibleWithin$` -->
<!-- The `data-fvw` attribute passes focus to `this.focusVisibleWithin$` -->
<!-- The following `class` field should match the `#isButton` class field below -->
<a
class="fvw tw-w-full tw-truncate tw-border-none tw-bg-transparent tw-p-0 tw-text-start !tw-text-alt2 hover:tw-text-alt2 hover:tw-no-underline focus:tw-outline-none"
class="tw-w-full tw-truncate tw-border-none tw-bg-transparent tw-p-0 tw-text-start !tw-text-alt2 hover:tw-text-alt2 hover:tw-no-underline focus:tw-outline-none"
data-fvw
[routerLink]="route"
[relativeTo]="relativeTo"
[attr.aria-label]="ariaLabel || text"
@@ -92,7 +93,8 @@
<!-- Class field should match `#isAnchor` class field above -->
<button
type="button"
class="fvw tw-w-full tw-truncate tw-border-none tw-bg-transparent tw-p-0 tw-text-start !tw-text-alt2 hover:tw-text-alt2 hover:tw-no-underline focus:tw-outline-none"
class="tw-w-full tw-truncate tw-border-none tw-bg-transparent tw-p-0 tw-text-start !tw-text-alt2 hover:tw-text-alt2 hover:tw-no-underline focus:tw-outline-none"
data-fvw
(click)="mainContentClicked.emit()"
>
<ng-container *ngTemplateOutlet="anchorAndButtonContent"></ng-container>

View File

@@ -39,11 +39,15 @@ export class NavItemComponent extends NavBaseComponent {
}
/**
* The design spec calls for the an outline to wrap the entire element when the template's anchor/button has :focus-visible.
* Usually, we would use :focus-within for this. However, that matches when a child element has :focus instead of :focus-visible.
* The design spec calls for the an outline to wrap the entire element when the template's
* anchor/button has :focus-visible. Usually, we would use :focus-within for this. However, that
* matches when a child element has :focus instead of :focus-visible.
*
* Currently, the browser does not have a pseudo selector that combines these two, e.g. :focus-visible-within (WICG/focus-visible#151)
* To make our own :focus-visible-within functionality, we use event delegation on the host and manually check if the focus target (denoted with the .fvw class) matches :focus-visible. We then map that state to some styles, so the entire component can have an outline.
* Currently, the browser does not have a pseudo selector that combines these two, e.g.
* :focus-visible-within (WICG/focus-visible#151). To make our own :focus-visible-within
* functionality, we use event delegation on the host and manually check if the focus target
* (denoted with the data-fvw attribute) matches :focus-visible. We then map that state to some
* styles, so the entire component can have an outline.
*/
protected focusVisibleWithin$ = new BehaviorSubject(false);
protected fvwStyles$ = this.focusVisibleWithin$.pipe(
@@ -53,7 +57,7 @@ export class NavItemComponent extends NavBaseComponent {
);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.focusVisibleWithin$.next(target.matches(".fvw:focus-visible"));
this.focusVisibleWithin$.next(target.matches("[data-fvw]:focus-visible"));
}
@HostListener("focusout")
onFocusOut() {

View File

@@ -2,9 +2,9 @@
// @ts-strict-ignore
import {
CdkVirtualScrollViewport,
CdkVirtualScrollableWindow,
CdkFixedSizeVirtualScroll,
CdkVirtualForOf,
CdkVirtualScrollableWindow,
} from "@angular/cdk/scrolling";
import { CommonModule } from "@angular/common";
import {

View File

@@ -21,7 +21,7 @@ $body-bg: $white;
$body-color: #333333;
$font-family-sans-serif:
"DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
$h1-font-size: 1.7rem;