ComponentsActions

Record actions menu

The More button on every record page and peek. Everything you can do to the record that isn't its one primary action.

Playground

Press the More button, then change the controls. The code under the preview lists only the props you changed.

import { RecordActionsMenu } from '@/ui/record-actions-menu';<RecordActionsMenu name="Halcyon Bank" />

On a company

Aligned to the button's right edge, 4px below. Logging and scheduling first, then the record's own actions, then Archive. Merge and Delete sit apart at the bottom; Delete is the only red item and always asks to confirm.

import {
  ArchiveIcon,
  ArrowsMergeIcon,
  BriefcaseIcon,
  CalendarPlusIcon,
  CrosshairSimpleIcon,
  GlobeIcon,
  NotePencilIcon,
  ProhibitIcon,
  TrashIcon,
} from '@phosphor-icons/react';
import { DropdownMenuItem } from '@/ui/dropdown-menu';
import { RecordActionsMenu } from '@/ui/record-actions-menu';

// The company page's More menu: logging and scheduling first, the record's own actions, Archive, then Merge and Delete apart.
export default function RecordActionsMenuDefault() {
  return (
    <RecordActionsMenu
      name="Halcyon Bank"
      width="md"
      danger={
        <>
          <DropdownMenuItem>
            <ArrowsMergeIcon />
            Merge with…
          </DropdownMenuItem>
          <DropdownMenuItem variant="destructive">
            <TrashIcon />
            Delete company
          </DropdownMenuItem>
        </>
      }
    >
      <DropdownMenuItem shortcut={['Mod', 'E']}>
        <NotePencilIcon />
        Log activity
      </DropdownMenuItem>
      <DropdownMenuItem>
        <CalendarPlusIcon />
        Schedule meeting
      </DropdownMenuItem>
      <DropdownMenuItem>
        <GlobeIcon />
        Fill from website
      </DropdownMenuItem>
      <DropdownMenuItem>
        <BriefcaseIcon />
        Add job
      </DropdownMenuItem>
      <DropdownMenuItem>
        <CrosshairSimpleIcon />
        Add to target list
      </DropdownMenuItem>
      <DropdownMenuItem>
        <ProhibitIcon />
        Mark do not contact
      </DropdownMenuItem>
      <DropdownMenuItem>
        <ArchiveIcon />
        Archive
      </DropdownMenuItem>
    </RecordActionsMenu>
  );
}

In a peek

Actions that aren't built yet stay in the menu with a Soon tag, disabled and skipped by the arrow keys, so the menu doesn't change shape. Ask Flo sits apart at the bottom.

import { ArchiveIcon, CalendarPlusIcon, FileTextIcon, NotePencilIcon, SparkleIcon, UsersThreeIcon } from '@phosphor-icons/react';
import { DropdownMenuItem } from '@/ui/dropdown-menu';
import { RecordActionsMenu } from '@/ui/record-actions-menu';

// In an application peek. Actions that aren't built yet stay in place with a Soon tag, disabled and skipped by the arrows.
export default function RecordActionsMenuPeek() {
  return (
    <RecordActionsMenu
      name="Maya Chen’s application"
      width="lg"
      danger={
        <DropdownMenuItem>
          <SparkleIcon />
          Ask Flo
        </DropdownMenuItem>
      }
    >
      <DropdownMenuItem>
        <NotePencilIcon />
        Log activity
      </DropdownMenuItem>
      <DropdownMenuItem>
        <CalendarPlusIcon />
        Schedule meeting
      </DropdownMenuItem>
      <DropdownMenuItem>
        <ArchiveIcon />
        Archive
      </DropdownMenuItem>
      <DropdownMenuItem soon>
        <UsersThreeIcon />
        Schedule CCM
      </DropdownMenuItem>
      <DropdownMenuItem soon>
        <FileTextIcon />
        Prepare CV draft
      </DropdownMenuItem>
    </RecordActionsMenu>
  );
}

Archived, and without the right

An archived record offers Restore. Logging and merging stay in place, disabled, with the reason under them. Delete is for an Owner or Admin: anyone else sees it disabled with why, never hidden, so the menu keeps its shape between records and people.

import { ArrowCounterClockwiseIcon, ArrowsMergeIcon, CalendarPlusIcon, NotePencilIcon, TrashIcon } from '@phosphor-icons/react';
import { DropdownMenuItem } from '@/ui/dropdown-menu';
import { RecordActionsMenu } from '@/ui/record-actions-menu';

// An archived company offers Restore. Logging and merging stay in place, disabled with the reason, so the menu keeps its shape.
// Delete is for an Owner or Admin; a Recruiter sees it disabled with why.
export default function RecordActionsMenuArchived() {
  return (
    <RecordActionsMenu
      name="Orbital Freight"
      width="lg"
      danger={
        <>
          <DropdownMenuItem disabled description="Restore the company first.">
            <ArrowsMergeIcon />
            Merge with…
          </DropdownMenuItem>
          <DropdownMenuItem variant="destructive" disabled description="Only Owners and Admins can delete.">
            <TrashIcon />
            Delete company
          </DropdownMenuItem>
        </>
      }
    >
      <DropdownMenuItem disabled description="Restore the company first.">
        <NotePencilIcon />
        Log activity
      </DropdownMenuItem>
      <DropdownMenuItem disabled description="Restore the company first.">
        <CalendarPlusIcon />
        Schedule meeting
      </DropdownMenuItem>
      <DropdownMenuItem>
        <ArrowCounterClockwiseIcon />
        Restore
      </DropdownMenuItem>
    </RecordActionsMenu>
  );
}

Motion

The menu uses the Popup motion. Press Replay to close and open it again.

import { ArchiveIcon, NotePencilIcon } from '@phosphor-icons/react';
import { useState } from 'react';
import { Button } from '@/ui/button';
import { DropdownMenuItem } from '@/ui/dropdown-menu';
import { RecordActionsMenu } from '@/ui/record-actions-menu';

// Replay closes the menu, then opens it again, so the 120ms exit and the 160ms entry run back to back.
export default function RecordActionsMenuMotion() {
  const [open, setOpen] = useState(false);
  const replay = () => {
    setOpen(false);
    setTimeout(() => setOpen(true), 400);
  };
  return (
    <div className="flex items-start gap-150">
      <Button variant="ghost" onClick={replay}>
        Replay
      </Button>
      <RecordActionsMenu name="Northbridge Talent" open={open} onOpenChange={setOpen} modal={false}>
        <DropdownMenuItem>
          <NotePencilIcon />
          Log activity
        </DropdownMenuItem>
        <DropdownMenuItem>
          <ArchiveIcon />
          Archive
        </DropdownMenuItem>
      </RecordActionsMenu>
    </div>
  );
}

On this page