BridgeHandbookDraft
For agents
Menu
Draft

Labels and icons that change

Controls whose text or icon changes in place.

When a control's result shows on the control itself — Copy becoming Copied, Sync becoming Synced — it changes in place, keeps its size, and is announced to screen readers.

The problem

Some actions finish at once and have nothing else to show: Copy, Copy invite link, Sync now. If the control doesn't change, people click again and still aren't sure it worked. If only an icon changes, screen-reader users miss it. And a "Copied" that shows when the copy failed is worse than nothing.

What to do

  • Show the result on the control. Copy becomes "Copied" with a green check for about 1.5 seconds, then goes back. Sync goes Sync now → Syncing… → Synced.
  • Keep it in view. A menu row that shows its own result keeps the menu open. If the control disappears after the click (a menu that closes), confirm with a toast instead.
  • Say it out loud, and only if it's true. The change is announced through a polite live region. A copy that failed shows as an error, never as "Copied".

Which one do I use?

SituationDo thisBridge example
Copy an email or phone numberCopyField: the row's Copy hint becomes "Copied"Profile contact info
Copy a link from a buttonThe button's label and icon change in placeCopy invite link → Copied
Copy from a ⋮ menucloseOnClick={false} on the row, so the menu stays open and the row shows the resultCopy profile link → Copied
The menu closes when you choose (a split button's caret)A Toast confirms instead, since the row is goneIntro link copied to clipboard
The copy failedAn error toast, never "Copied"Couldn't copy the intro link. Try again.
Sync with a visible labelA ghost Button: refresh → spinner → checkSync now → Syncing… → Synced
Sync as an icon onlyThe refresh IconButton; the state is in its label (Live and running states)Rail calendar line
The result lasts (sharing)Not a flash: the control shows the new state from now onShare network → Invited

See it work

Live examples built from the package on the sample network. Click through them.

Copy a contact detail

Click a row: "Copy" becomes "Copied" with a check, then goes back. Screen readers hear "Copied".

In a ⋮ menu: the row shows its own result

Open the menu and copy the profile link. The menu stays open so you can see "Copied".

Your profile

A button that keeps its size

"Copied" is shorter than "Copy invite link", so the button has a fixed width and nothing next to it moves.

Sync now, Syncing…, Synced

The label follows the work, then settles back.

What to write

PartRuleExample
BeforeVerb and object.Copy invite link · Copy profile link · Sync now
CopiedOne word, past tense, no exclamation mark.Copied
While runningThe verb in -ing with an ellipsis.Syncing…
DonePast tense, one word.Synced
Toast insteadPast tense and object, under 10 words.Intro link copied to clipboard
Failed"Couldn't" and what to do.Couldn't copy the intro link. Try again.
Lasting stateThe state, not the action you just took.Invited

Approved, not built yet

  • A control that changes its label keeps a fixed width, so the row doesn't shift.

Accessibility

  • The new label is announced through a polite live region (CopyField does this for you; do the same for your own buttons).
  • The control keeps its own name: CopyField is "Copy email: leah.okonkwo@saltmarsh.example" whatever it shows.
  • The check is decorative; the word carries the meaning, so color is never the only signal.
  • Keeping the menu open leaves focus on the row that changed, so keyboard users see the result too.
KeysWhat happens
Enter / SpaceCopies, or starts the sync.
↑ / ↓Moves between menu rows.
EscCloses the menu.

Components this uses

Each opens that component’s own page, with its options and code.

ComponentIts job here
CopyFieldAn email or phone number whose action is Copy, with "Copied" built in and announced.
ActionMenucloseOnClick={false} on a row that shows its own result.
ButtonCopy invite link (secondary) and a labeled Sync (ghost, xs, loading).
IconButtonIcon-only Sync: refresh → spinner → check.
ToastConfirms a copy when the control that did it has gone.

Where Bridge OS differs today

Follow this page, not the gap.

  • Bridge OS writes "Copied!" with an exclamation mark in two places and "Copied" in another; it should be one (exclamation marks are still undecided).
  • How long "Copied" stays varies: 1.5 seconds in CopyField, 2 seconds for Copy profile link and Copy invite link.
  • The profile menu's "Copied" check hard-codes its green (#0EA02E) instead of the success token.

Sources

  • Bridge OS copy-field.tsx
  • components.md → ActionMenuItem
  • Bridge OS calendar-sync-status.tsx
  • Package CopyField
  • Bridge OS connectors-tab.tsx (invites tab)
  • Bridge OS profile-tab.tsx
  • Bridge OS profile-intro-actions.tsx; components.md → ButtonGroup / Copy intro link
  • Bridge OS hooks/use-copy-intro-link.ts
  • Bridge OS calendar-sync-status.tsx (CalendarSyncButton)
  • Bridge OS recently-met-rail.tsx (sharing states comment)
  • Handbook Voice and tone page
  • Proposals approved by Aman 2026-11-02.