Skip to content

CreateStreamFab's expandable action menu has no click-outside-to-dismiss handler #1061

Description

@mikewheeleer

Description

src/components/CreateStreamFab.tsx renders an expandable role="menu" when actions are provided:

const handleMainClick = () => {
  if (hasActions) {
    setExpanded((value) => !value);
  } else {
    onCreateStream();
  }
};

const handleMenuKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
  ...
  if (event.key === "Escape") {
    setExpanded(false);
    return;
  }
  ...
};

The menu only closes via Escape, selecting a menu item, or clicking the FAB button itself again. There is no document-level click/mousedown listener to close the menu when the user clicks anywhere else on the page — unlike the equivalent dropdown pattern already implemented elsewhere in this codebase, e.g. src/components/presence/PresenceBadge.tsx, which registers a mousedown listener on document to close its popover on outside clicks. A user who opens the FAB's action menu and then clicks elsewhere on the page (without pressing Escape or selecting an action) will find the menu still open, floating over unrelated page content.

Requirements

  • CreateStreamFab's expanded action menu must close when the user clicks/taps outside the FAB and its menu, matching the outside-click dismissal pattern already used by PresenceBadge.tsx.
  • Existing Escape-to-close and item-selection-closes behavior must be preserved.

Suggested execution

  1. Add a mousedown (or pointerdown) listener on document while expanded is true, checking whether the event target is outside a ref wrapping the whole CreateStreamFab root, and calling setExpanded(false) if so — mirroring PresenceBadge.tsx's handleOutsideClick implementation.
  2. Ensure the listener is added/removed correctly across expanded state transitions to avoid leaks.
  3. Add a test simulating a click outside the FAB while its menu is open and asserting the menu closes.

Acceptance criteria

  • Clicking outside the open FAB menu closes it.
  • Escape and item-selection close behavior remain unchanged.
  • A regression test covers the outside-click dismissal.

Security notes

None; UX consistency/correctness fix.

Guidelines

  • Minimum 95% test coverage
  • Timeframe: 96 hours

Metadata

Metadata

Assignees

No one assigned

    Labels

    GRANTFOX OSSGrantFox open-source campaign taskMAYBE REWARDEDMay be rewarded under the GrantFox campaignOfficial Campaign | FWC26GrantFox FWC26 official campaigna11ybugSomething isn't workingfrontend

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions