Skip to content

Commit 23cb3de

Browse files
committed
fix(#2054): add maxwidth prop to dropdown, textarea and tooltip
1 parent fa698c9 commit 23cb3de

File tree

18 files changed

+367
-100
lines changed

18 files changed

+367
-100
lines changed

libs/angular-components/src/lib/components/dropdown/dropdown.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { fireEvent } from "@testing-library/dom";
2121
[testId]="testId"
2222
[id]="id"
2323
[width]="width"
24+
[maxWidth]="maxWidth"
2425
[mt]="mt"
2526
[mr]="mr"
2627
[mb]="mb"
@@ -56,6 +57,7 @@ class TestDropdownComponent {
5657
placeholder?: string;
5758
testId?: string;
5859
width?: string;
60+
maxWidth?: string;
5961
mt?: Spacing;
6062
mb?: Spacing;
6163
ml?: Spacing;
@@ -93,6 +95,7 @@ describe("GoABDropdown", () => {
9395
component.testId = "foo";
9496
component.id = "foo-dropdown";
9597
component.width = "200px";
98+
component.maxWidth = "400px";
9699
component.mt = "s";
97100
component.mr = "m";
98101
component.mb = "l";
@@ -115,6 +118,7 @@ describe("GoABDropdown", () => {
115118
expect(el?.getAttribute("arialabel")).toBe("Label");
116119
expect(el?.getAttribute("arialabelledby")).toBe("foo-dropdown-label");
117120
expect(el?.getAttribute("autocomplete")).toBe("off");
121+
expect(el?.getAttribute("maxwidth")).toBe("400px");
118122

119123
// Check options
120124
const dropdownItems = el.querySelectorAll("goa-dropdown-item");

libs/angular-components/src/lib/components/dropdown/dropdown.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { GoabControlValueAccessor } from "../base.component";
3535
[attr.placeholder]="placeholder"
3636
[attr.testid]="testId"
3737
[attr.width]="width"
38+
[attr.maxwidth]="maxWidth"
3839
[attr.relative]="relative"
3940
[attr.autocomplete]="autoComplete"
4041
[id]="id"
@@ -63,6 +64,7 @@ export class GoabDropdown extends GoabControlValueAccessor {
6364
@Input({ transform: booleanAttribute }) native?: boolean;
6465
@Input() placeholder?: string;
6566
@Input() width?: string;
67+
@Input() maxWidth?: string;
6668
@Input() autoComplete?: string;
6769
/***
6870
* @deprecated This property has no effect and will be removed in a future version

libs/angular-components/src/lib/components/tooltip/tooltip.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ class TestTooltipComponent {
1414
/** do nothing **/
1515
}
1616

17+
@Component({
18+
template: `
19+
<goab-tooltip content="This is a tooltip" maxWidth="300px" testId="foo-maxwidth">
20+
<goab-icon type="information-circle"></goab-icon>
21+
</goab-tooltip>
22+
`,
23+
})
24+
class TestTooltipMaxWidthComponent {
25+
/** do nothing **/
26+
}
27+
1728
describe("GoABTooltip", () => {
1829
let fixture: ComponentFixture<TestTooltipComponent>;
1930

@@ -38,3 +49,23 @@ describe("GoABTooltip", () => {
3849
expect(goaIcon?.getAttribute("type")).toBe("information-circle");
3950
});
4051
});
52+
53+
describe("GoABTooltip with maxWidth", () => {
54+
let fixture: ComponentFixture<TestTooltipMaxWidthComponent>;
55+
56+
beforeEach(async () => {
57+
await TestBed.configureTestingModule({
58+
declarations: [TestTooltipMaxWidthComponent],
59+
imports: [GoabTooltip, GoabIcon],
60+
}).compileComponents();
61+
62+
fixture = TestBed.createComponent(TestTooltipMaxWidthComponent);
63+
fixture.detectChanges();
64+
});
65+
66+
it("should render with maxWidth property", () => {
67+
const el = fixture.nativeElement.querySelector("goa-tooltip");
68+
expect(el?.getAttribute("maxwidth")).toBe("300px");
69+
expect(el?.getAttribute("testid")).toBe("foo-maxwidth");
70+
});
71+
});

libs/angular-components/src/lib/components/tooltip/tooltip.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { GoabBaseComponent } from "../base.component";
1515
[attr.content]="getContentAsString()"
1616
[attr.halign]="hAlign"
1717
[attr.testid]="testId"
18+
[attr.maxwidth]="maxWidth"
1819
[attr.mt]="mt"
1920
[attr.mb]="mb"
2021
[attr.ml]="ml"
@@ -37,6 +38,7 @@ export class GoabTooltip extends GoabBaseComponent {
3738
@Input() position?: GoabTooltipPosition;
3839
@Input() content?: string | TemplateRef<unknown>;
3940
@Input() hAlign?: GoabTooltipHorizontalAlignment;
41+
@Input() maxWidth?: string;
4042

4143
getContentAsString(): string {
4244
return this.content instanceof TemplateRef ? "" : this.content || "";

libs/react-components/specs/dropdown.browser.spec.tsx

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ describe("Dropdown Component", () => {
99
};
1010

1111
describe("Dropdown", () => {
12-
1312
it("should render with the default props", async () => {
1413
// Setup
1514

@@ -137,6 +136,39 @@ describe("Dropdown Component", () => {
137136
expect(computedStyle.width).toBe("300px");
138137
});
139138
});
139+
140+
it("applies maxWidth constraint when width exceeds maxWidth", async () => {
141+
const Component = () => {
142+
return (
143+
<GoabDropdown
144+
name="favcolor"
145+
testId="favcolor-max"
146+
width="800px"
147+
maxWidth="320px"
148+
onChange={noop}
149+
>
150+
<GoabDropdownItem label="Red" value="red" />
151+
<GoabDropdownItem label="Blue" value="blue" />
152+
<GoabDropdownItem label="Green" value="green" />
153+
</GoabDropdown>
154+
);
155+
};
156+
157+
const result = render(<Component />);
158+
const dropdown = result.getByTestId("favcolor-max");
159+
160+
await vi.waitFor(() => {
161+
const styleAttr = dropdown.element().getAttribute("style") || "";
162+
// Provided width custom prop present
163+
expect(styleAttr).toContain("--width: 800px");
164+
// Max width style applied to host when maxWidth prop provided (from Svelte template conditional)
165+
expect(styleAttr).toMatch(/max-width:\s*320px/);
166+
167+
const computedStyle = window.getComputedStyle(dropdown.element());
168+
// Effective width should not exceed maxWidth constraint
169+
expect(computedStyle.width).toBe("320px");
170+
});
171+
});
140172
});
141173

142174
describe("Popover position", () => {
@@ -437,7 +469,7 @@ describe("Dropdown Component", () => {
437469
// Result
438470
expect(onChange).toHaveBeenCalledTimes(1);
439471
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({
440-
name: "options",
472+
name: "options",
441473
value: 2
442474
}));
443475
});
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { render } from "vitest-browser-react";
2+
3+
import { GoabTextArea } from "../src";
4+
import { expect, describe, it, vi } from "vitest";
5+
6+
describe("TextArea Browser Tests", () => {
7+
const noop = () => {
8+
// noop
9+
};
10+
11+
it("should render textarea component", async () => {
12+
const Component = () => {
13+
return (
14+
<div data-testid="container">
15+
<GoabTextArea
16+
name="description"
17+
testId="textarea"
18+
placeholder="Enter description"
19+
onChange={noop}
20+
/>
21+
</div>
22+
);
23+
};
24+
25+
const result = render(<Component />);
26+
const container = result.getByTestId("container");
27+
28+
// Verify elements are rendered
29+
expect(container).toBeTruthy();
30+
31+
// Wait for the goa-textarea custom element to be present
32+
await vi.waitFor(
33+
() => {
34+
const textareaEl = container.element().querySelector("goa-textarea");
35+
expect(textareaEl).toBeTruthy();
36+
},
37+
{ timeout: 3000 },
38+
);
39+
});
40+
41+
it("should apply maxWidth", async () => {
42+
const Component = () => {
43+
return (
44+
<div data-testid="container">
45+
<GoabTextArea
46+
name="longtext"
47+
testId="textarea-maxwidth"
48+
width="800px"
49+
maxWidth="300px"
50+
value={"Lorem ipsum dolor sit amet, consectetur adipiscing elit. ".repeat(10)}
51+
onChange={noop}
52+
/>
53+
</div>
54+
);
55+
};
56+
57+
const result = render(<Component />);
58+
const container = result.getByTestId("container");
59+
60+
await vi.waitFor(
61+
() => {
62+
const host = container.element().querySelector("goa-textarea");
63+
expect(host).toBeTruthy();
64+
65+
const computed = window.getComputedStyle(host as HTMLElement);
66+
expect(computed.maxWidth).toBe("300px");
67+
68+
// Width should not exceed the maxWidth
69+
const numericWidth = parseInt(computed.width || "0", 10);
70+
expect(numericWidth).toBeGreaterThan(0);
71+
expect(numericWidth).toBeLessThanOrEqual(300);
72+
},
73+
{ timeout: 3000 },
74+
);
75+
});
76+
});

0 commit comments

Comments
 (0)