GitHub

Command Palette

Search for a command to run...

Menu

(A) One-liner

Menu is a compound component that shows a dropdown when pressing a trigger (button, etc.), and provides item selection/check functionality. Menu.Trigger manages open state (controlled/uncontrolled), outside click close, and close on select, while Menu.Dropdown/DropdownItem/DropdownCheckItem compose the menu UI.


(B) Installation (Track A / Track B)

Track A (CLI / local install)

Track A: add Menu
pnpm dlx @fleet-ui/cli add Menu
Track A: import
import { Menu } from '@fleet-ui/local/components';

Track B (NPM package)

Track B: import
import { Menu } from '@fleet-ui/components';

(Required) Per-component Dependencies

Menu uses RN Modal + Reanimated for dropdown display/animation. Also uses react-native-worklets for worklet scheduling.

Recommended runtime deps
pnpm add react-native-reanimated react-native-gesture-handler react-native-worklets react-native-unistyles

(D) Core Features & Usage

D-1. Most Common Scenario (Minimal Example)

Menu basic usage
import { Menu, Button } from '@fleet-ui/components';
 
export function Example() {
  return (
    <Menu.Trigger
      dropdown={
        <Menu.Dropdown header={<Menu.Header>Sort</Menu.Header>}>
          <Menu.DropdownItem onPress={() => {}}>Latest</Menu.DropdownItem>
          <Menu.DropdownItem onPress={() => {}}>Popular</Menu.DropdownItem>
        </Menu.Dropdown>
      }
    >
      <Button>Open Menu</Button>
    </Menu.Trigger>
  );
}

D-2. CheckItem: Menu.DropdownCheckItem

DropdownCheckItem internally toggles checked state and calls onCheckedChange(next). Also, when closeOnSelect=true, menu closes after checking.

Menu check items
import { useState } from 'react';
import { Menu, Button } from '@fleet-ui/components';
 
export function Example() {
  const [checked, setChecked] = useState(false);
 
  return (
    <Menu.Trigger
      dropdown={
        <Menu.Dropdown>
          <Menu.DropdownCheckItem checked={checked} onCheckedChange={setChecked}>
            Option A
          </Menu.DropdownCheckItem>
        </Menu.Dropdown>
      }
    >
      <Button>Options</Button>
    </Menu.Trigger>
  );
}

D-3. Close Policy

  • closeOnOutsidePress: Close when pressing overlay (outside area) (default true)
  • closeOnSelect: Close on item selection (default true)

If menu has UX where multiple items need to be checked consecutively like "settings toggles," consider closeOnSelect={false}.


(E) Internal State / Shared Value / Animation

E-1. State Model (Trigger)

Menu.Trigger supports both controlled/uncontrolled.

  • controlled: If open exists, isOpen = open
  • uncontrolled: Start internal state with defaultOpen, toggle internally with setInternalOpen

Also uses separate modalVisible state to maintain Modal until close animation completes.

E-2. Reanimated / Shared Value

Dropdown display animation is processed with these shared values:

  • opacity: 0 → 1 (open), 1 → 0 (close)
  • scaleX/scaleY: 0 → 1 transition (with delay)

On close, modal is hidden in animation completion callback.


(F) Accessibility

  • Dropdown container: accessibilityRole="menu" (Menu.Dropdown)
  • Menu items: accessibilityRole="menuitem" (Menu.DropdownItem/DropdownCheckItem)
  • Trigger modal scope:
    • accessibilityViewIsModal
    • importantForAccessibility="yes"
    • Close support via onAccessibilityEscape

Recommended rules:

  • If item text is string, it's automatically used as label, but provide accessibilityLabel when using custom children.

(G) Props Table

Reference: Public types from packages/components/src/Menu/Menu.types.ts.

PropTypeRequiredDefaultDescriptionPlatform notes
openbooleanNo-Open state (controlled)
defaultOpenbooleanNofalseInitial open (uncontrolled)
onOpen() => voidNo-Open callback
onClose() => voidNo-Close callback
childrenReactNodeYes-Trigger element (button, etc.)onPress can be injected internally
dropdownReactNodeYes-Dropdown (Menu.Dropdown)
placementMenuPlacementNo'bottom-start'Placement positionIncludes screen boundary correction
closeOnOutsidePressbooleanNotrueClose on outside click
closeOnSelectbooleanNotrueClose on item selectionPassed via context
PropTypeRequiredDefaultDescription
headerReactNodeNo-Header (Menu.Header recommended)
size'sm' | 'md' | 'lg'No'md'Dropdown size
rounded'none' | 'sm' | 'md' | 'lg'No'md'Rounded
shadow'none' | 'sm' | 'md' | 'lg'No'md'Shadow
childrenReactNodeYes-Items
PropTypeRequiredDefaultDescription
leftReactNodeNo-Left slot
rightReactNodeNo-Right slot (Menu.DropdownIcon recommended)
childrenReactNodeYes-Text/content
PropTypeRequiredDefaultDescriptionPlatform notes
leftReactNodeNo-Left slot
rightReactNodeNo-Right slot
checkedbooleanNofalseCheck state
onCheckedChange(checked: boolean) => voidNo-Check change callback
colorScheme'primary' | 'neutral' | 'error' | 'success' | 'warning' | 'info'No'primary'Color on check
childrenReactNodeYes-Text/content
  • Menu.Header: MenuHeaderProps (children, style)
  • Menu.DropdownIcon: MenuDropdownIconProps (icon, size?, color?, strokeWidth?)