Phi
Dropdown Menu
@dicehub/phiv1.0.0-beta.1

Dropdown Menu

Displays a menu to the user, such as a set of actions or functions, triggered by a button.

<script setup>
import { PhPlus } from "@phosphor-icons/vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger>
      <Button :icon="PhPlus">Add</Button>
    </DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="worker">Worker</DropdownMenu.Item>
      <DropdownMenu.Item value="pages">Pages</DropdownMenu.Item>
      <DropdownMenu.Item value="kv">KV Namespace</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Installation

Barrel

import { DropdownMenu } from "@dicehub/phi";

Granular

import { DropdownMenu } from "@dicehub/phi/components/dropdown";

Usage

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger>
      <Button>Menu</Button>
    </DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="edit">Edit</DropdownMenu.Item>
      <DropdownMenu.Item value="duplicate">Duplicate</DropdownMenu.Item>
      <DropdownMenu.Separator />
      <DropdownMenu.Item value="delete" variant="danger">Delete</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Examples

Basic Dropdown

<script setup>
import { PhPlus } from "@phosphor-icons/vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger>
      <Button :icon="PhPlus">Add</Button>
    </DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="worker">Worker</DropdownMenu.Item>
      <DropdownMenu.Item value="pages">Pages</DropdownMenu.Item>
      <DropdownMenu.Item value="kv">KV Namespace</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Inset Items

Use inset on items without an icon to align their text with items that have one.

<script setup>
import { PhCopy, PhPencilSimple, PhTrash } from "@phosphor-icons/vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger><Button>Edit</Button></DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="rename" :icon="PhPencilSimple">Rename</DropdownMenu.Item>
      <DropdownMenu.Item value="duplicate" :icon="PhCopy">Duplicate</DropdownMenu.Item>
      <DropdownMenu.Separator />
      <DropdownMenu.Item value="move" inset>Move to folder</DropdownMenu.Item>
      <DropdownMenu.Item value="favorite" inset>Add to favorites</DropdownMenu.Item>
      <DropdownMenu.Separator />
      <DropdownMenu.Item value="delete" :icon="PhTrash" variant="danger">Delete</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Handling Item Clicks

Use select handlers on DropdownMenu.Item to handle actions.

<script setup>
import { ref } from "vue";
import { PhCopy, PhPencilSimple, PhTrash } from "@phosphor-icons/vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";

const lastAction = ref("");
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger><Button>Actions</Button></DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="duplicate" :icon="PhCopy" @select="lastAction = 'Duplicated'">
        Duplicate
      </DropdownMenu.Item>
      <DropdownMenu.Item value="rename" :icon="PhPencilSimple" @select="lastAction = 'Renamed'">
        Rename
      </DropdownMenu.Item>
      <DropdownMenu.Separator />
      <DropdownMenu.Item value="delete" :icon="PhTrash" variant="danger" @select="lastAction = 'Deleted'">
        Delete
      </DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Checkbox Items

Use DropdownMenu.CheckboxItem for toggleable options that can be independently checked or unchecked.

<script setup>
import { ref } from "vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";

const showSidebar = ref(true);
const showLineNumbers = ref(false);
const wordWrap = ref(true);
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger><Button>View Options</Button></DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Group>
        <DropdownMenu.Label>Display</DropdownMenu.Label>
        <DropdownMenu.CheckboxItem v-model:checked="showSidebar" value="sidebar">
          Show sidebar
        </DropdownMenu.CheckboxItem>
        <DropdownMenu.CheckboxItem v-model:checked="showLineNumbers" value="line-numbers">
          Show line numbers
        </DropdownMenu.CheckboxItem>
        <DropdownMenu.CheckboxItem v-model:checked="wordWrap" value="word-wrap">
          Word wrap
        </DropdownMenu.CheckboxItem>
      </DropdownMenu.Group>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Nested Menu with Radio Selection

Use DropdownMenu.Sub, SubTrigger, and SubContent to create nested submenus with radio selections.

<script setup>
import { ref } from "vue";
import { PhCreditCard, PhMoon, PhSignOut, PhUser } from "@phosphor-icons/vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";

const language = ref("en");
const timezone = ref("America/Los_Angeles");
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger><Button :icon="PhUser">Account</Button></DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="profile" :icon="PhUser">Profile</DropdownMenu.Item>
      <DropdownMenu.Item value="billing" :icon="PhCreditCard">Billing</DropdownMenu.Item>
      <DropdownMenu.Item value="theme" :icon="PhMoon">Dark mode</DropdownMenu.Item>
      <DropdownMenu.Sub>
        <DropdownMenu.SubTrigger>Language</DropdownMenu.SubTrigger>
        <DropdownMenu.SubContent>
          <DropdownMenu.RadioGroup v-model="language">
            <DropdownMenu.RadioItem value="en">English<DropdownMenu.RadioItemIndicator /></DropdownMenu.RadioItem>
            <DropdownMenu.RadioItem value="es">Español<DropdownMenu.RadioItemIndicator /></DropdownMenu.RadioItem>
          </DropdownMenu.RadioGroup>
        </DropdownMenu.SubContent>
      </DropdownMenu.Sub>
      <DropdownMenu.Separator />
      <DropdownMenu.Item value="logout" :icon="PhSignOut" variant="danger">Log out</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Custom Trigger with Avatar

Use DropdownMenu.Trigger with a custom focusable element when the trigger is not a standard Button.

<script setup>
import { PhGear, PhSignOut, PhUser } from "@phosphor-icons/vue";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger>
      <button class="avatar-trigger" type="button" aria-label="Open account menu">MR</button>
    </DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.Item value="profile" :icon="PhUser">Profile</DropdownMenu.Item>
      <DropdownMenu.Item value="settings" :icon="PhGear">Settings</DropdownMenu.Item>
      <DropdownMenu.Separator />
      <DropdownMenu.Item value="logout" :icon="PhSignOut" variant="danger">Log out</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

Use DropdownMenu.LinkItem for semantic menu items that navigate to a URL.

<script setup>
import { PhArrowSquareOut, PhBookOpen, PhGear } from "@phosphor-icons/vue";
import { Button } from "@dicehub/phi/components/button";
import { DropdownMenu } from "@dicehub/phi/components/dropdown";
</script>

<template>
  <DropdownMenu>
    <DropdownMenu.Trigger><Button>Resources</Button></DropdownMenu.Trigger>
    <DropdownMenu.Content>
      <DropdownMenu.LinkItem href="/docs/installation" :icon="PhGear">Settings</DropdownMenu.LinkItem>
      <DropdownMenu.LinkItem href="/docs" :icon="PhBookOpen">Documentation</DropdownMenu.LinkItem>
      <DropdownMenu.Separator />
      <DropdownMenu.LinkItem href="https://developers.cloudflare.com" target="_blank" :icon="PhArrowSquareOut">
        Developer Docs
      </DropdownMenu.LinkItem>
    </DropdownMenu.Content>
  </DropdownMenu>
</template>

API Reference