- {{ titleText | async }}
- {{ subtitleText | async }}
+ {{ titleText() }}
+ {{ subtitleText() }}
-
+
+
-
- {{ dividerOrLabel | async }}
-
+ @if (hasChildren()) {
+
{{ dividerOrLabel() }}
+ }
+
-
+
`,
})
-export class SignUpAuthScreenComponent implements AfterContentInit {
- private ui = inject(FirebaseUI);
-
- @Input() signInRoute: string = "";
- @ViewChild("contentContainer") contentContainer!: ElementRef;
- private _hasProjectedContent = false;
-
- get hasContent(): boolean {
- return this._hasProjectedContent;
- }
-
- get titleText() {
- return this.ui.translation("labels", "register");
- }
-
- get subtitleText() {
- return this.ui.translation("prompts", "enterDetailsToCreate");
- }
-
- get dividerOrLabel() {
- return this.ui.translation("messages", "dividerOr");
- }
+export class SignUpAuthScreenComponent {
+ titleText = injectTranslation("labels", "register");
+ subtitleText = injectTranslation("prompts", "enterDetailsToCreate");
+ dividerOrLabel = injectTranslation("messages", "dividerOr");
- ngAfterContentInit() {
- // Set to true initially to ensure the container is rendered
- this._hasProjectedContent = true;
+ signUp = output();
+ signIn = output();
- // We need to use setTimeout to check after the view is rendered
- setTimeout(() => {
- // Check if there's any actual content in the container
- if (this.contentContainer && this.contentContainer.nativeElement) {
- const container = this.contentContainer.nativeElement;
- // Only consider it to have content if there are child nodes that aren't just whitespace
- this._hasProjectedContent = Array.from(container.childNodes as NodeListOf).some((node: Node) => {
- return (
- node.nodeType === Node.ELEMENT_NODE ||
- (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim() !== "")
- );
- });
- } else {
- this._hasProjectedContent = false;
- }
- });
- }
+ contentContainer = viewChild.required("contentContainer");
+ hasChildren = computed(() => this.contentContainer().nativeElement.children.length > 0);
}
diff --git a/packages/angular/src/lib/components/button/button.component.spec.ts b/packages/angular/src/lib/components/button/button.component.spec.ts
index 0c19e343..a223cbb9 100644
--- a/packages/angular/src/lib/components/button/button.component.spec.ts
+++ b/packages/angular/src/lib/components/button/button.component.spec.ts
@@ -14,86 +14,17 @@
* limitations under the License.
*/
-import { Component } from "@angular/core";
-import { ComponentFixture, TestBed } from "@angular/core/testing";
-import { By } from "@angular/platform-browser";
-import { ButtonComponent } from "./button.component";
-import { describe, it, expect, beforeEach } from "vitest";
-
-@Component({
- template: `
- Click me
- Secondary
- Custom Class
- Disabled
- `,
- standalone: true,
- imports: [ButtonComponent],
-})
-class TestHostComponent {
- clicks = 0;
-
- handleClick() {
- this.clicks++;
- }
-}
-
-describe("ButtonComponent", () => {
- let fixture: ComponentFixture;
- let hostComponent: TestHostComponent;
-
- beforeEach(async () => {
- await TestBed.configureTestingModule({
- imports: [ButtonComponent, TestHostComponent],
- }).compileComponents();
-
- fixture = TestBed.createComponent(TestHostComponent);
- hostComponent = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it("renders with default variant (primary)", () => {
- const buttonEl = fixture.debugElement.query(By.css('[data-testid="test-button"]'));
- const button = buttonEl.nativeElement.querySelector("button");
-
- expect(button).toBeTruthy();
- expect(button.classList.contains("fui-button")).toBe(true);
- expect(button.classList.contains("fui-button--secondary")).toBe(false);
- expect(button.textContent.trim()).toBe("Click me");
- });
-
- it("renders with secondary variant", () => {
- const buttonEl = fixture.debugElement.query(By.css('[data-testid="secondary-button"]'));
- const button = buttonEl.nativeElement.querySelector("button");
+import { describe, it, expect, beforeEach, afterEach } from "vitest";
+import { render, screen, fireEvent, } from "@testing-library/angular";
- expect(button).toBeTruthy();
- expect(button.classList.contains("fui-button")).toBe(true);
- expect(button.classList.contains("fui-button--secondary")).toBe(true);
- });
-
- it("applies custom className", () => {
- const buttonEl = fixture.debugElement.query(By.css('[data-testid="custom-class-button"]'));
-
- expect(buttonEl.nativeElement.classList.contains("custom-class")).toBe(true);
- });
-
- it("handles click events", () => {
- const buttonEl = fixture.debugElement.query(By.css('[data-testid="test-button"]'));
- const button = buttonEl.nativeElement.querySelector("button");
-
- expect(hostComponent.clicks).toBe(0);
-
- button.click();
- fixture.detectChanges();
-
- expect(hostComponent.clicks).toBe(1);
- });
-
- it("can be disabled", () => {
- const buttonEl = fixture.debugElement.query(By.css('[data-testid="disabled-button"]'));
- const button = buttonEl.query(By.css("button"));
+import { ButtonComponent } from "./button.component";
- expect(button).toBeTruthy();
- expect(button.nativeElement.disabled).toBe(true);
+describe("
`,
standalone: true,
diff --git a/packages/angular/src/lib/components/card/card.component.ts b/packages/angular/src/lib/components/card/card.component.ts
index 313905ca..a1ef438c 100644
--- a/packages/angular/src/lib/components/card/card.component.ts
+++ b/packages/angular/src/lib/components/card/card.component.ts
@@ -23,7 +23,8 @@ import { CommonModule } from "@angular/common";
imports: [],
template: `
-
+
+
`,
})
@@ -33,12 +34,10 @@ export class CardComponent {}
selector: "fui-card-header",
standalone: true,
imports: [CommonModule],
- host: {
- style: "display: block;",
- },
template: `
`,
})
@@ -67,3 +66,15 @@ export class CardTitleComponent {}
`,
})
export class CardSubtitleComponent {}
+
+@Component({
+ selector: "fui-card-content",
+ standalone: true,
+ imports: [CommonModule],
+ template: `
+
+
+
+ `,
+})
+export class CardContentComponent {}
diff --git a/packages/angular/src/lib/components/country-selector/country-selector.component.ts b/packages/angular/src/lib/components/country-selector/country-selector.component.ts
index b7701a0a..f4cf37c8 100644
--- a/packages/angular/src/lib/components/country-selector/country-selector.component.ts
+++ b/packages/angular/src/lib/components/country-selector/country-selector.component.ts
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-import { Component, EventEmitter, Input, Output } from "@angular/core";
+import { Component, computed, model } from "@angular/core";
import { CommonModule } from "@angular/common";
-import { CountryData, countryData } from "@firebase-ui/core";
+import { CountryCode, CountryData, countryData } from "@firebase-ui/core";
import { FormsModule } from "@angular/forms";
@Component({
@@ -24,14 +24,14 @@ import { FormsModule } from "@angular/forms";
standalone: true,
imports: [CommonModule, FormsModule],
template: `
-
+
-
{{ value.emoji }}
+
{{ selected().emoji }}
-
{{ value.dialCode }}
+
{{ selected().dialCode }}