Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { fireEvent } from "@testing-library/dom";
[testId]="testId"
[id]="id"
[width]="width"
[maxWidth]="maxWidth"
[mt]="mt"
[mr]="mr"
[mb]="mb"
Expand Down Expand Up @@ -56,6 +57,7 @@ class TestDropdownComponent {
placeholder?: string;
testId?: string;
width?: string;
maxWidth?: string;
mt?: Spacing;
mb?: Spacing;
ml?: Spacing;
Expand Down Expand Up @@ -93,6 +95,7 @@ describe("GoABDropdown", () => {
component.testId = "foo";
component.id = "foo-dropdown";
component.width = "200px";
component.maxWidth = "400px";
component.mt = "s";
component.mr = "m";
component.mb = "l";
Expand All @@ -115,6 +118,7 @@ describe("GoABDropdown", () => {
expect(el?.getAttribute("arialabel")).toBe("Label");
expect(el?.getAttribute("arialabelledby")).toBe("foo-dropdown-label");
expect(el?.getAttribute("autocomplete")).toBe("off");
expect(el?.getAttribute("maxwidth")).toBe("400px");

// Check options
const dropdownItems = el.querySelectorAll("goa-dropdown-item");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { GoabControlValueAccessor } from "../base.component";
[attr.placeholder]="placeholder"
[attr.testid]="testId"
[attr.width]="width"
[attr.maxwidth]="maxWidth"
[attr.relative]="relative"
[attr.autocomplete]="autoComplete"
[id]="id"
Expand Down Expand Up @@ -63,6 +64,7 @@ export class GoabDropdown extends GoabControlValueAccessor {
@Input({ transform: booleanAttribute }) native?: boolean;
@Input() placeholder?: string;
@Input() width?: string;
@Input() maxWidth?: string;
@Input() autoComplete?: string;
/***
* @deprecated This property has no effect and will be removed in a future version
Expand Down
31 changes: 31 additions & 0 deletions libs/angular-components/src/lib/components/tooltip/tooltip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ class TestTooltipComponent {
/** do nothing **/
}

@Component({
template: `
<goab-tooltip content="This is a tooltip" maxWidth="300px" testId="foo-maxwidth">
<goab-icon type="information-circle"></goab-icon>
</goab-tooltip>
`,
})
class TestTooltipMaxWidthComponent {
/** do nothing **/
}

describe("GoABTooltip", () => {
let fixture: ComponentFixture<TestTooltipComponent>;

Expand All @@ -38,3 +49,23 @@ describe("GoABTooltip", () => {
expect(goaIcon?.getAttribute("type")).toBe("information-circle");
});
});

describe("GoABTooltip with maxWidth", () => {
let fixture: ComponentFixture<TestTooltipMaxWidthComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TestTooltipMaxWidthComponent],
imports: [GoabTooltip, GoabIcon],
}).compileComponents();

fixture = TestBed.createComponent(TestTooltipMaxWidthComponent);
fixture.detectChanges();
});

it("should render with maxWidth property", () => {
const el = fixture.nativeElement.querySelector("goa-tooltip");
expect(el?.getAttribute("maxwidth")).toBe("300px");
expect(el?.getAttribute("testid")).toBe("foo-maxwidth");
});
});
2 changes: 2 additions & 0 deletions libs/angular-components/src/lib/components/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { GoabBaseComponent } from "../base.component";
[attr.content]="getContentAsString()"
[attr.halign]="hAlign"
[attr.testid]="testId"
[attr.maxwidth]="maxWidth"
[attr.mt]="mt"
[attr.mb]="mb"
[attr.ml]="ml"
Expand All @@ -37,6 +38,7 @@ export class GoabTooltip extends GoabBaseComponent {
@Input() position?: GoabTooltipPosition;
@Input() content?: string | TemplateRef<unknown>;
@Input() hAlign?: GoabTooltipHorizontalAlignment;
@Input() maxWidth?: string;

getContentAsString(): string {
return this.content instanceof TemplateRef ? "" : this.content || "";
Expand Down
136 changes: 133 additions & 3 deletions libs/react-components/specs/dropdown.browser.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ describe("Dropdown Component", () => {
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all the browser tests, you're only testing basic px measurements. You should also have tests using % and ch to make sure those work as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR updated.


describe("Dropdown", () => {

it("should render with the default props", async () => {
// Setup

Expand Down Expand Up @@ -110,7 +109,7 @@ describe("Dropdown Component", () => {
expect(dropdown.element().getAttribute("style")).toContain("--width: 500px");
await dropdown.click();
expect(popover.element().getAttribute("open")).toBe("true");
expect(popoverDiv.element().getAttribute("style")).toContain("width: min(500px, 100%)");
expect(dropdown.element().getAttribute("style")).toContain("--width: 500px");
})
});

Expand All @@ -137,6 +136,137 @@ describe("Dropdown Component", () => {
expect(computedStyle.width).toBe("300px");
});
});

it("applies maxWidth constraint when width exceeds maxWidth", async () => {
const Component = () => {
return (
<GoabDropdown
name="favcolor"
testId="favcolor-max"
width="800px"
maxWidth="320px"
onChange={noop}
>
<GoabDropdownItem label="Red" value="red" />
<GoabDropdownItem label="Blue" value="blue" />
<GoabDropdownItem label="Green" value="green" />
</GoabDropdown>
);
};

const result = render(<Component />);
const dropdown = result.getByTestId("favcolor-max");

await vi.waitFor(() => {
const styleAttr = dropdown.element().getAttribute("style") || "";
expect(styleAttr).toContain("--width: 800px");
expect(styleAttr).toMatch(/max-width:\s*320px/);

const computedStyle = window.getComputedStyle(dropdown.element());
// Effective width should not exceed maxWidth constraint
expect(computedStyle.width).toBe("320px");
});
});

it("supports percentage width units", async () => {
const Component = () => {
return (
<GoabDropdown
name="favcolor"
testId="percentage-dropdown"
width="75%"
onChange={noop}
>
<GoabDropdownItem label="Red" value="red" />
<GoabDropdownItem label="Blue" value="blue" />
<GoabDropdownItem label="Green" value="green" />
</GoabDropdown>
);
};

const result = render(<Component />);
const dropdown = result.getByTestId("percentage-dropdown");

await vi.waitFor(() => {
// Check that width is set with percentage unit
const styleAttr = dropdown.element().getAttribute("style") || "";
expect(styleAttr).toContain("--width: 75%");

// Check computed width is percentage of container
const computedStyle = window.getComputedStyle(dropdown.element());
expect(computedStyle.width).toMatch(/^\d+(\.\d+)?px$/); // Should be converted to pixels

// Check that it's a reasonable percentage width (should be substantial but not too large)
const dropdownWidth = parseFloat(computedStyle.width);
expect(dropdownWidth).toBeGreaterThan(100); // Should be substantial
expect(dropdownWidth).toBeLessThan(800); // But not too large for 75%
});
});

it("supports character (ch) width units", async () => {
const Component = () => {
return (
<GoabDropdown
name="favcolor"
testId="ch-dropdown"
width="30ch"
onChange={noop}
>
<GoabDropdownItem label="Red" value="red" />
<GoabDropdownItem label="Blue" value="blue" />
<GoabDropdownItem label="Green" value="green" />
</GoabDropdown>
);
};

const result = render(<Component />);
const dropdown = result.getByTestId("ch-dropdown");

await vi.waitFor(() => {
// Check that width is set with ch unit
const styleAttr = dropdown.element().getAttribute("style") || "";
expect(styleAttr).toContain("--width: 30ch");

// Check computed width is applied
const computedStyle = window.getComputedStyle(dropdown.element());
expect(computedStyle.width).toMatch(/^\d+(\.\d+)?px$/); // Browser converts ch to px

// Should have a reasonable width (ch is approximately font width)
const dropdownWidth = parseFloat(computedStyle.width);
expect(dropdownWidth).toBeGreaterThan(200); // Should be substantial width
expect(dropdownWidth).toBeLessThan(600); // But not too large
});
});

it("defaults to px when no unit is provided", async () => {
const Component = () => {
return (
<GoabDropdown
name="favcolor"
testId="no-unit-dropdown"
width="250"
onChange={noop}
>
<GoabDropdownItem label="Red" value="red" />
<GoabDropdownItem label="Blue" value="blue" />
<GoabDropdownItem label="Green" value="green" />
</GoabDropdown>
);
};

const result = render(<Component />);
const dropdown = result.getByTestId("no-unit-dropdown");

await vi.waitFor(() => {
// Check that width is converted to px when no unit provided
const styleAttr = dropdown.element().getAttribute("style") || "";
expect(styleAttr).toContain("--width: 250px");

// Check computed width matches expected px value
const computedStyle = window.getComputedStyle(dropdown.element());
expect(computedStyle.width).toBe("250px");
});
});
});

describe("Popover position", () => {
Expand Down Expand Up @@ -437,7 +567,7 @@ describe("Dropdown Component", () => {
// Result
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({
name: "options",
name: "options",
value: 2
}));
});
Expand Down
Loading