# WorkspaceButton

> The server switcher on the frame — the server's avatar, its name and a chevron, one button that opens the server list.

Source: https://raft-design.botiverse.build/components/workspace-button. Generated from the current release; where it differs from what you remember, this page is right.

WorkspaceButton shows which server you are in and opens the list to switch. It looks the same everywhere it appears: on the left of the web top bar, at the top of a phone's Home on the web, and at the top of Home in the mobile app.

```tsx
import { useState } from "react";
import {
  Avatar,
  AvatarFallback,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuTrigger,
  WorkspaceButton,
  WorkspaceButtonName,
} from "@botiverse/raft-ui";

const SERVERS = ["Acme", "Botiverse", "The Long Name Of A Server That Does Not Fit"];

export function WorkspaceButtonComposition() {
  const [server, setServer] = useState(SERVERS[0]);

  return (
    <div className="flex h-14 w-80 max-w-full items-center rounded-control bg-layer-frame px-1.5">
      <DropdownMenu>
        <DropdownMenuTrigger render={<WorkspaceButton aria-label={server} />}>
          <Avatar type="server" size="sm">
            <AvatarFallback>{server.slice(0, 1)}</AvatarFallback>
          </Avatar>
          <WorkspaceButtonName>{server}</WorkspaceButtonName>
        </DropdownMenuTrigger>
        <DropdownMenuContent>
          <DropdownMenuRadioGroup value={server} onValueChange={setServer}>
            {SERVERS.map((name) => (
              <DropdownMenuRadioItem key={name} value={name}>
                {name}
              </DropdownMenuRadioItem>
            ))}
          </DropdownMenuRadioGroup>
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  );
}
```

## When to use

| Situation                                                | Use                                                                   |
| -------------------------------------------------------- | --------------------------------------------------------------------- |
| The current server, on the frame, opening the list       | WorkspaceButton                                                       |
| Another server, one click away, beside the button        | The workspace strip: the server's [Avatar](https://raft-design.botiverse.build/components/avatar.md) alone |
| The server on the desktop rail, when there is no top bar | The rail's workspace tile ([AppRail](https://raft-design.botiverse.build/components/app-rail.md))        |

## Anatomy

- `WorkspaceButton`: the on-frame `md` [Button](https://raft-design.botiverse.build/components/button.md): 36px high, 10px each side, `text-subhead` bold in `foreground-on-frame`, with `fill-frame-pressed` on hover, on press and while the list is open. It ends with a 16px chevron, 4px after the name. The chevron is part of the button and always shows.
- The server's [Avatar](https://raft-design.botiverse.build/components/avatar.md), `type="server" size="sm"` (27px): the server's logo, or its initial in yellow on ink. 8px before the name.
- `WorkspaceButtonName`: the server's name, at most 200px, then an ellipsis.
- Optional, between the name and the chevron: the globe, when the server's public page is on.

## Behavior

- Opening the list: on desktop a menu under the button, 256px wide; on a phone a popover anchored under the top bar, 8px from each side ([Switching servers](https://raft-design.botiverse.build/components.md#switching-servers)).
- The button shrinks from the name. The avatar and the chevron keep their size, so the button reads as a switcher in any width.
- The button keeps its avatar when the workspace strip shows beside it.
- Place it by its avatar: the avatar's left edge is on the page's content line (16px on a phone), and the press fill reaches past it by the button's padding ([Alignment](https://raft-design.botiverse.build/foundations/alignment.md)).

## States

- **Unread elsewhere:** when another server has unread items, an attention dot sits on the avatar's top-right corner (`AvatarBadge` with `offset={["100%", 0]}`).
- **Pressed and open:** `fill-frame-pressed` under the whole button.

## Accessibility

- The button's name is the server's name. When another server has unread items, say so in the label ("Acme, another server has unread items").
- The chevron is decorative (`aria-hidden`).

## API

### WorkspaceButton

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `loading` | `boolean` |  |  |
| `loadingLabel` | `string` |  |  |
| `focusableWhenDisabled` | `boolean` | `false` | Whether the button should be focusable when disabled. |
| `nativeButton` | `boolean` | `true` | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### WorkspaceButtonName

Also takes the attributes of its element.

## Changes

- 0.15.0 (Design System): **Server switcher**: on every surface (the web top bar, the phone web's Home and the mobile app) the server switcher is one button: the server's avatar, its name and a chevron, whatever sits beside it. The tilted ink pill on the phone web's Home is retired; build the switcher from `WorkspaceButton`, `Avatar type="server" size="sm"` and `WorkspaceButtonName`.
