Blocks
TeamSwitcher
The workspace picker at the top of an app sidebar — current team's avatar and name in the trigger, the rest in a dropdown under it. Three weights via `variant`, a `collapsed` state that drops to just the avatar, and room for a "Create team" action below the list. `UserMenu` is its opposite number at the sidebar's foot.
<UiTeamSwitcher :teams="..." />Options
One block per prop — what it does, and what it looks like set.
Teams
requiredteams is the list to choose between. Each one needs a label; an avatar is drawn from the team's initials when you don't supply one, so a bare list of names already renders something sensible. The first team is what shows until a selection is made.
Model value
modelValue is the selected team's value, falling back to its label where there isn't one. Bind it with v-model when something else needs to know which team is current — leave it off entirely and the switcher tracks the selection itself, which is what every other example here does.
Selected: Vue
Variant
variant is how much the trigger asserts itself. subtle gives it a surface and a ring, so it reads as a control in its own right — right for a sidebar header, where it's the first thing on the page. soft keeps the fill and drops the ring; ghost shows nothing until you hover it, which suits a switcher sitting among other quiet chrome.
subtle
soft
ghost
State
state mirrors a parent Sidebar's slot prop of the same name. collapsed drops the name and the caret and centers the avatar, which is all that fits at icon width — hand it straight through from the sidebar's header slot and the switcher shrinks with everything else.
Items
items are extra menu groups under the list of teams, each behind its own divider — the actions that belong to the switcher rather than to any one team. They're plain DropdownMenu items, so icons, colors, shortcuts and nested children all work as they do there.
Examples
The component in real use: compositions that answer "how do I build X with this", rather than one prop at a time.
Descriptions and shortcut hints — a second line per team, and `kbds` on their rows
description shows under the name in the trigger; kbds renders a shortcut hint on that team's menu row. The hint is display only — nothing here binds ⌘1, that part is yours.
API Reference
Generated from the component's source — props, slots and emits as the component actually declares them.
Props
teamsrequiredTeam[]string"subtle" | "soft" | "ghost"'subtle'"expanded" | "collapsed"'expanded'DropdownMenuItem[][]Slots
defaultEmits
update:modelValue[value: string]select[team: Team]Types
type Variant = "subtle" | "soft" | "ghost";interface Team {
/**
* What `v-model` identifies this team by. Falls back to `label`, which is enough whenever the
* names are unique.
*/
value?: string;
/** The team's name, shown in the trigger and on its menu row. */
label: string;
/**
* The avatar shown beside the name, in the trigger and the menu alike. Omit it and the team's
* initials are drawn from `label`.
*/
avatar?: {
src?: string;
alt?: string;
firstName?: string;
lastName?: string;
shape?: "circle" | "square";
};
/** A quieter second line under the name in the trigger — a plan, a role, an environment. */
description?: string;
/** Shortcut hint rendered on this team's menu row. Display only; binding the key is yours. */
kbds?: Array<string | { value?: string }>;
/** Greys the row out and stops it being selected. */
disabled?: boolean;
}interface DropdownMenuItem {
label?: string;
/**
* The row's icon: an icon name, or `{ name, color, fill }` to also tint just the icon
* (independent of `color`, which tints the whole row) or render its filled variant.
*/
icon?: string | MenuItemIcon;
status?: "online" | "offline" | "away" | "dnd" | "busy";
avatar?: {
src?: string;
alt?: string;
firstName?: string;
lastName?: string;
status?: "online" | "offline" | "away" | "dnd" | "busy";
shape?: "circle" | "square";
};
badge?: {
text?: number | string;
color?: "primary" | "secondary" | "success" | "warning" | "error" | "info" | "pending" | "neutral";
};
kbds?: Array<string | { value?: string }>;
type?: "link" | "label" | "separator" | "checkbox";
color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "pending" | "neutral";
checked?: boolean;
disabled?: boolean;
onSelect?: (e: Event) => void;
onUpdateChecked?: (checked: boolean) => void;
children?: DropdownMenuItem[] | DropdownMenuItem[][];
class?: any;
to?: string;
target?: string;
}