Files
HausApp/.agents/skills/vercel-react-native-skills/rules/ui-menus.md
René Schober 4e34270786 initial commit
2026-03-13 06:23:06 +01:00

4.5 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Use Native Menus for Dropdowns and Context Menus HIGH native accessibility, platform-consistent UX user-interface, menus, context-menus, zeego, accessibility

Use Native Menus for Dropdowns and Context Menus

Use native platform menus instead of custom JS implementations. Native menus provide built-in accessibility, consistent platform UX, and better performance. Use zeego for cross-platform native menus.

Incorrect (custom JS menu):

import { useState } from "react";
import { View, Pressable, Text } from "react-native";

function MyMenu() {
  const [open, setOpen] = useState(false);

  return (
    <View>
      <Pressable onPress={() => setOpen(!open)}>
        <Text>Open Menu</Text>
      </Pressable>
      {open && (
        <View style={{ position: "absolute", top: 40 }}>
          <Pressable onPress={() => console.log("edit")}>
            <Text>Edit</Text>
          </Pressable>
          <Pressable onPress={() => console.log("delete")}>
            <Text>Delete</Text>
          </Pressable>
        </View>
      )}
    </View>
  );
}

Correct (native menu with zeego):

import * as DropdownMenu from "zeego/dropdown-menu";

function MyMenu() {
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>
        <Pressable>
          <Text>Open Menu</Text>
        </Pressable>
      </DropdownMenu.Trigger>

      <DropdownMenu.Content>
        <DropdownMenu.Item key="edit" onSelect={() => console.log("edit")}>
          <DropdownMenu.ItemTitle>Edit</DropdownMenu.ItemTitle>
        </DropdownMenu.Item>

        <DropdownMenu.Item key="delete" destructive onSelect={() => console.log("delete")}>
          <DropdownMenu.ItemTitle>Delete</DropdownMenu.ItemTitle>
        </DropdownMenu.Item>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  );
}

Context menu (long-press):

import * as ContextMenu from "zeego/context-menu";

function MyContextMenu() {
  return (
    <ContextMenu.Root>
      <ContextMenu.Trigger>
        <View style={{ padding: 20 }}>
          <Text>Long press me</Text>
        </View>
      </ContextMenu.Trigger>

      <ContextMenu.Content>
        <ContextMenu.Item key="copy" onSelect={() => console.log("copy")}>
          <ContextMenu.ItemTitle>Copy</ContextMenu.ItemTitle>
        </ContextMenu.Item>

        <ContextMenu.Item key="paste" onSelect={() => console.log("paste")}>
          <ContextMenu.ItemTitle>Paste</ContextMenu.ItemTitle>
        </ContextMenu.Item>
      </ContextMenu.Content>
    </ContextMenu.Root>
  );
}

Checkbox items:

import * as DropdownMenu from "zeego/dropdown-menu";

function SettingsMenu() {
  const [notifications, setNotifications] = useState(true);

  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>
        <Pressable>
          <Text>Settings</Text>
        </Pressable>
      </DropdownMenu.Trigger>

      <DropdownMenu.Content>
        <DropdownMenu.CheckboxItem
          key="notifications"
          value={notifications}
          onValueChange={() => setNotifications((prev) => !prev)}
        >
          <DropdownMenu.ItemIndicator />
          <DropdownMenu.ItemTitle>Notifications</DropdownMenu.ItemTitle>
        </DropdownMenu.CheckboxItem>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  );
}

Submenus:

import * as DropdownMenu from "zeego/dropdown-menu";

function MenuWithSubmenu() {
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>
        <Pressable>
          <Text>Options</Text>
        </Pressable>
      </DropdownMenu.Trigger>

      <DropdownMenu.Content>
        <DropdownMenu.Item key="home" onSelect={() => console.log("home")}>
          <DropdownMenu.ItemTitle>Home</DropdownMenu.ItemTitle>
        </DropdownMenu.Item>

        <DropdownMenu.Sub>
          <DropdownMenu.SubTrigger key="more">
            <DropdownMenu.ItemTitle>More Options</DropdownMenu.ItemTitle>
          </DropdownMenu.SubTrigger>

          <DropdownMenu.SubContent>
            <DropdownMenu.Item key="settings">
              <DropdownMenu.ItemTitle>Settings</DropdownMenu.ItemTitle>
            </DropdownMenu.Item>

            <DropdownMenu.Item key="help">
              <DropdownMenu.ItemTitle>Help</DropdownMenu.ItemTitle>
            </DropdownMenu.Item>
          </DropdownMenu.SubContent>
        </DropdownMenu.Sub>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  );
}

Reference: Zeego Documentation