1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 08:43:33 +00:00

[PM-14422] Vault Carousel (#12791)

* collect tailwind styles from the `libs/vault/*`

- Some unique styles were not showing in storybook

* initial add of carousel component

* initial add of carousel stories

* move carousel button to a standalone component for organization

* add key manager for carousel buttons

* add tab panel role to slide component

* make carousel slide focusable when it does not contain focusable elements

* add aria live to carousel slides

* add labels for carousel slide buttons

* emit slide change event

* move icons to carousel-icons folder

* add barrel file for carousel

* move protected properties

* remove underscore

* allow differing heights of carousel slides

* update interactive styles for the carousel icons

* allow for focus styled on carousel buttons

* fix tests

* fix imports

* add method to render each slide and get the height of the tallest slide

- This avoids consumers having to pass in a height.
- The height of the tallest slide is needed because it will stop the carousel from jumping around as the user scrolls.

* add comment to content property

* remove rem calculation
This commit is contained in:
Nick Krantz
2025-01-22 08:45:35 -06:00
committed by GitHub
parent 02e10b56f5
commit e26670c029
16 changed files with 621 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
import { TemplatePortal } from "@angular/cdk/portal";
import { Component, OnInit, TemplateRef, ViewChild, ViewContainerRef } from "@angular/core";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { VaultCarouselContentComponent } from "./carousel-content.component";
@Component({
selector: "app-test-template-ref",
standalone: true,
imports: [VaultCarouselContentComponent],
template: `
<ng-template #template>
<p>Test Template Content</p>
</ng-template>
<vault-carousel-content [content]="portal"></vault-carousel-content>
`,
})
class TestTemplateRefComponent implements OnInit {
// Test template content by creating a wrapping component and then pass a portal to the carousel content component.
@ViewChild("template", { static: true }) template!: TemplateRef<any>;
portal!: TemplatePortal;
constructor(private viewContainerRef: ViewContainerRef) {}
ngOnInit() {
this.portal = new TemplatePortal(this.template, this.viewContainerRef);
}
}
describe("VaultCarouselContentComponent", () => {
let fixture: ComponentFixture<TestTemplateRefComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [VaultCarouselContentComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestTemplateRefComponent);
fixture.detectChanges();
});
it("displays content", () => {
const carouselContent = fixture.debugElement.query(By.directive(VaultCarouselContentComponent));
expect(carouselContent.nativeElement.textContent).toBe("Test Template Content");
});
it("sets aria attributes for screen readers", () => {
const carouselContent = fixture.debugElement.query(By.directive(VaultCarouselContentComponent));
const wrappingDiv = carouselContent.nativeElement.querySelector("div");
expect(wrappingDiv.getAttribute("aria-live")).toBe("polite");
expect(wrappingDiv.getAttribute("aria-atomic")).toBe("false");
});
});