From e9bfa2e2a59a536fff3accb8b5a6ebed01bb5a81 Mon Sep 17 00:00:00 2001 From: Thomas Jeffery Date: Mon, 13 Apr 2026 15:33:58 -0600 Subject: [PATCH] fix(#3630): drawer exit animation, close button alignment, docs updates --- .../routes/bugs/3630/bug3630.component.html | 107 +++++++++++ .../src/routes/bugs/3630/bug3630.component.ts | 17 ++ .../src/routes/bugs/3630/bug3630.route.json | 6 + .../src/app/routes/bugs/bug3630.route.ts | 9 + apps/prs/react/src/routes/bugs/bug3630.tsx | 174 ++++++++++++++++++ docs/src/content/components/drawer.mdx | 2 +- docs/src/data/configurations/drawer.ts | 6 +- .../specs/drawer.browser.spec.tsx | 21 +-- .../specs/pushdrawer.browser.spec.tsx | 19 +- .../src/components/drawer/Drawer.svelte | 42 +++-- .../src/components/drawer/drawer.spec.ts | 86 +++++---- 11 files changed, 412 insertions(+), 77 deletions(-) create mode 100644 apps/prs/angular/src/routes/bugs/3630/bug3630.component.html create mode 100644 apps/prs/angular/src/routes/bugs/3630/bug3630.component.ts create mode 100644 apps/prs/angular/src/routes/bugs/3630/bug3630.route.json create mode 100644 apps/prs/react/src/app/routes/bugs/bug3630.route.ts create mode 100644 apps/prs/react/src/routes/bugs/bug3630.tsx diff --git a/apps/prs/angular/src/routes/bugs/3630/bug3630.component.html b/apps/prs/angular/src/routes/bugs/3630/bug3630.component.html new file mode 100644 index 0000000000..56c0626db6 --- /dev/null +++ b/apps/prs/angular/src/routes/bugs/3630/bug3630.component.html @@ -0,0 +1,107 @@ +
+

Bug #3630: Drawer refinements

+

+ + View on GitHub + +

+ +
+ +

Test Cases

+ +

Test 1: Right drawer (animation + alignment)

+

+ Open and close. Check slide-in and slide-out animation. Check heading and close button + vertical alignment. +

+ Open right drawer + + +

+ Check the slide-out animation when closing. The close button should align well with + the heading text. +

+
+ +
+ +

Test 2: Right drawer with actions

+

Actions should use start alignment with compact buttons.

+ Open right drawer with actions + + + + Save + Cancel + + + + +

The action buttons below should be left-aligned and compact.

+
+ +
+ +

Test 3: Left drawer

+

Check slide-in from left and slide-out animation.

+ Open left drawer + + +

Check the slide-out animation when closing from the left side.

+
+ +
+ +

Test 4: Bottom drawer

+

Check slide-up from bottom and slide-down animation.

+ Open bottom drawer + + +

Check the slide-down animation when closing from the bottom.

+
+ +
+ +

Test 5: Long heading

+

Check alignment when the heading wraps to two lines.

+ Open drawer with long heading + + +

Check that the close button stays aligned properly when the heading wraps.

+
+
diff --git a/apps/prs/angular/src/routes/bugs/3630/bug3630.component.ts b/apps/prs/angular/src/routes/bugs/3630/bug3630.component.ts new file mode 100644 index 0000000000..4aa2f779ff --- /dev/null +++ b/apps/prs/angular/src/routes/bugs/3630/bug3630.component.ts @@ -0,0 +1,17 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { GoabDrawer, GoabButton, GoabButtonGroup } from "@abgov/angular-components"; + +@Component({ + standalone: true, + selector: "abgov-bug3630", + templateUrl: "./bug3630.component.html", + imports: [GoabDrawer, GoabButton, GoabButtonGroup], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class Bug3630Component { + rightOpen = false; + rightActionsOpen = false; + leftOpen = false; + bottomOpen = false; + longHeadingOpen = false; +} diff --git a/apps/prs/angular/src/routes/bugs/3630/bug3630.route.json b/apps/prs/angular/src/routes/bugs/3630/bug3630.route.json new file mode 100644 index 0000000000..f5f8a6db7c --- /dev/null +++ b/apps/prs/angular/src/routes/bugs/3630/bug3630.route.json @@ -0,0 +1,6 @@ +{ + "title": "Drawer refinements", + "path": "bugs/3630", + "id": "3630", + "type": "bug" +} diff --git a/apps/prs/react/src/app/routes/bugs/bug3630.route.ts b/apps/prs/react/src/app/routes/bugs/bug3630.route.ts new file mode 100644 index 0000000000..57ebd9c5fd --- /dev/null +++ b/apps/prs/react/src/app/routes/bugs/bug3630.route.ts @@ -0,0 +1,9 @@ +import { Bug3630Route } from "../../../routes/bugs/bug3630"; +import type { PrRouteDefinition } from "../../route-manifest"; +export default { + type: "bug", + id: "3630", + path: "bugs/3630", + title: "Drawer refinements", + component: Bug3630Route, +} satisfies PrRouteDefinition; diff --git a/apps/prs/react/src/routes/bugs/bug3630.tsx b/apps/prs/react/src/routes/bugs/bug3630.tsx new file mode 100644 index 0000000000..d132132e55 --- /dev/null +++ b/apps/prs/react/src/routes/bugs/bug3630.tsx @@ -0,0 +1,174 @@ +import { useState } from "react"; +import { + GoabBlock, + GoabButton, + GoabButtonGroup, + GoabDetails, + GoabDivider, + GoabDrawer, + GoabLink, + GoabText, +} from "@abgov/react-components"; + +export function Bug3630Route() { + const [rightOpen, setRightOpen] = useState(false); + const [rightActionsOpen, setRightActionsOpen] = useState(false); + const [leftOpen, setLeftOpen] = useState(false); + const [bottomOpen, setBottomOpen] = useState(false); + const [longHeadingOpen, setLongHeadingOpen] = useState(false); + + return ( +
+ + Bug #3630: Drawer refinements + + + + + + View on GitHub + + + + + + 1. Exit animation should slide out (not just disappear). 2. Close button + alignment with heading. 3. Actions should use start alignment with compact + buttons. 4. Move category from content-layout to structure-navigation. + + + + + + + Test Cases + + Test 1: Right drawer (animation + alignment) + + Open and close. Check slide-in and slide-out animation. Check heading and close + button vertical alignment. + + + setRightOpen(true)}>Open right drawer + + + setRightOpen(false)} + > + + Check the slide-out animation when closing. The close button should align well + with the heading text. + + + + + + Test 2: Right drawer with actions + + Actions should use start alignment with compact buttons. + + + setRightActionsOpen(true)}> + Open right drawer with actions + + + + setRightActionsOpen(false)} + actions={ + + + Save + + setRightActionsOpen(false)} + > + Cancel + + + } + > + + The action buttons below should be left-aligned and compact. + + + + + + Test 3: Left drawer + Check slide-in from left and slide-out animation. + + setLeftOpen(true)}>Open left drawer + + + setLeftOpen(false)} + > + + Check the slide-out animation when closing from the left side. + + + + + + Test 4: Bottom drawer + Check slide-up from bottom and slide-down animation. + + setBottomOpen(true)}>Open bottom drawer + + + setBottomOpen(false)} + > + + Check the slide-down animation when closing from the bottom. + + + + + + Test 5: Long heading + Check alignment when the heading wraps to two lines. + + setLongHeadingOpen(true)}> + Open drawer with long heading + + + + setLongHeadingOpen(false)} + > + + Check that the close button stays aligned properly when the heading wraps. + + +
+ ); +} + +export default Bug3630Route; diff --git a/docs/src/content/components/drawer.mdx b/docs/src/content/components/drawer.mdx index cbeedbc838..2750d7e2ef 100644 --- a/docs/src/content/components/drawer.mdx +++ b/docs/src/content/components/drawer.mdx @@ -2,7 +2,7 @@ name: Drawer description: A panel that slides in from the side of the screen to display additional content or actions without navigating away from the current view. status: stable -category: content-layout +category: structure-and-navigation tags: - sections - structure and navigation diff --git a/docs/src/data/configurations/drawer.ts b/docs/src/data/configurations/drawer.ts index 428f2887b6..7fb08143b7 100644 --- a/docs/src/data/configurations/drawer.ts +++ b/docs/src/data/configurations/drawer.ts @@ -205,7 +205,7 @@ const handleSave = () => { open={isOpen} onClose={handleClose} actions={ - + Save @@ -244,7 +244,7 @@ const handleSave = () => { [actions]="actionsTpl" > - + Save Cancel {

Make changes to your settings here.

- + Save Cancel diff --git a/libs/react-components/specs/drawer.browser.spec.tsx b/libs/react-components/specs/drawer.browser.spec.tsx index e446afe8ee..c769481b30 100644 --- a/libs/react-components/specs/drawer.browser.spec.tsx +++ b/libs/react-components/specs/drawer.browser.spec.tsx @@ -16,7 +16,7 @@ describe("Drawer", () => { await vi.waitFor(async () => { const drawer = getByTestId(testId); expect(drawer).toBeInTheDocument(); - expect(drawer).toHaveStyle({ visibility: "hidden" }); + expect(drawer).toHaveStyle({ pointerEvents: "none" }); }); }); @@ -34,21 +34,20 @@ describe("Drawer", () => { await vi.waitFor(async () => { const drawer = getByTestId(testId); - expect(drawer).toHaveStyle({ visibility: "visible" }); + expect(drawer).toHaveStyle({ pointerEvents: "auto" }); }); }); it("calls onClose when the close button is clicked", async () => { const { getByTestId } = await render(); - await vi.waitFor(async () => { - const closeButton = getByTestId("drawer-close-button"); - expect(closeButton).toBeTruthy(); - await closeButton.click(); - - vi.waitFor(() => { - expect(handleOnClose).toHaveBeenCalled(); - }); + const closeButton = getByTestId("drawer-close-button"); + await vi.waitFor(() => { + expect(closeButton.element()).toBeTruthy(); + }); + await closeButton.click(); + await vi.waitFor(() => { + expect(handleOnClose).toHaveBeenCalled(); }); }); }); @@ -63,7 +62,7 @@ describe("Drawer", () => { await vi.waitFor(async () => { const drawer = getByTestId(testId); - expect(drawer).toHaveStyle({ visibility: "hidden" }); + expect(drawer).toHaveStyle({ pointerEvents: "none" }); }); }); }); diff --git a/libs/react-components/specs/pushdrawer.browser.spec.tsx b/libs/react-components/specs/pushdrawer.browser.spec.tsx index 858819ea15..1d2a454cc8 100644 --- a/libs/react-components/specs/pushdrawer.browser.spec.tsx +++ b/libs/react-components/specs/pushdrawer.browser.spec.tsx @@ -64,21 +64,20 @@ describe("PushDrawer", () => { await vi.waitFor(async () => { const drawer = getByTestId(`drawer-${testId}`); - expect(drawer).toHaveStyle({ visibility: "visible" }); + expect(drawer).toHaveStyle({ pointerEvents: "auto" }); }); }); it("calls onClose when the close button is clicked", async () => { const { getByTestId } = await render(); - await vi.waitFor(async () => { - const closeButton = getByTestId("drawer-close-button"); - expect(closeButton).toBeTruthy(); - await closeButton.click(); - - vi.waitFor(() => { - expect(handleOnClose).toHaveBeenCalled(); - }); + const closeButton = getByTestId("drawer-close-button"); + await vi.waitFor(() => { + expect(closeButton.element()).toBeTruthy(); + }); + await closeButton.click(); + await vi.waitFor(() => { + expect(handleOnClose).toHaveBeenCalled(); }); }); }); @@ -93,7 +92,7 @@ describe("PushDrawer", () => { await vi.waitFor(async () => { const drawer = getByTestId(`drawer-${testId}`); - expect(drawer).toHaveStyle({ visibility: "hidden" }); + expect(drawer).toHaveStyle({ pointerEvents: "none" }); }); }); }); diff --git a/libs/web-components/src/components/drawer/Drawer.svelte b/libs/web-components/src/components/drawer/Drawer.svelte index 76e639fde8..49efe89f8d 100644 --- a/libs/web-components/src/components/drawer/Drawer.svelte +++ b/libs/web-components/src/components/drawer/Drawer.svelte @@ -3,7 +3,10 @@ tag: "goa-drawer", props: { open: { type: "Boolean", reflect: true }, - closeButtonVisibility: { type: "String", attribute: "close-button-visibility" }, + closeButtonVisibility: { + type: "String", + attribute: "close-button-visibility", + }, }, }} /> @@ -12,12 +15,7 @@ import { fly } from "svelte/transition"; import noscroll from "../../common/no-scroll"; import { onDestroy, onMount, tick } from "svelte"; - import { - dispatch, - style, - styles, - typeValidator, - } from "../../common/utils"; + import { dispatch, style, styles, typeValidator } from "../../common/utils"; import { DrawerPosition, DrawerSize } from "../../common/types"; // ****** @@ -220,7 +218,7 @@