Skip to content

SeanBarker182/zeego

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Frame 32

Beautiful, native menus for React Native + Web, inspired by Radix UI.

  • πŸ•Ί Radix UI on Web
  • πŸ›« Native elements on iOS/Android (where possible)
  • 🌲 Same API cross-platform
  • 🌊 Works with Solito and Next.js
  • πŸ€– Supports Expo (with custom dev clients)
  • 🍦 Vanilla React Native too
  • 🎨 100% unstyled components

About Zeego

To learn more about Zeego and its approach to menus, you can watch Fernando Rojo's talk at App.js Conf.

The Zeego release happens at about 9:35.

Screen Shot 2022-08-29 at 8 43 30 PM

Installation

yarn add zeego

Install peer dependencies

If you're in a monorepo, you should install these in the directory of your native app.

iOS

yarn add react-native-ios-context-menu

Android

yarn add @react-native-menu/menu

Solito

As shown above, sure to install react-native-ios-context-menu and @react-native-menu/menu in your Expo folder (apps/expo).

You should also follow the Next.js steps below.

Next.js

You need to add zeego to your next-transpile-modules in next.config.js.

Expo

You need to use a custom development client, since react-native-ios-context-menu uses native code.

After installing, you'll need to rebuild your custom development client and app.

Vanilla React Native

Run pod install in your ios folder.

Philosophy

Optimized

  1. Use the best API possible
  2. Create the best experience for each platform, without concern for sharing styles
  3. Rely on built-in native menus for iOS and Android
  4. Everything ships unstyled

The API follows that of Radix UI closely.

Usage

import * as DropdownMenu from 'zeego/dropdown-menu'

See radix-ui's dropdown menu. It's really similar.

One difference is that DropdownMenu.Item needs a child DropdownMenu.ItemTitle, since React Native separates Text and View components.

<DropdownMenu.Item>
  <DropdownMenu.ItemTitle>Bookmark</DropdownMenu.ItemTitle>
  <DropdownMenu.ItemIcon iosIconName="bookmark">
    <YourIconComponent />
  </DropdownMenu.ItemIcon>
</DropdownMenu.Item>

Custom components

To use a custom component, you'll first need to create it.

Here is an example of a custom component using Dripsy:

import * as DropdownMenu from 'zeego/dropdown-menu'
import { styled } from 'dripsy'

const StyledMenuItem = styled(DropdownMenu.Item)({
  height: 32,
})

// this part is important
const DripsyMenuItem = DropdownMenu.create(StyledMenuItem, 'Item')

And now, you can use it:

<DripsyMenuItem key="fernando">
  <DropdownMenu.ItemTitle>Fernando</DropdownMenu.ItemTitle>
<DripsyMenuItem>

Under the hood, create applies a displayName to your component. This allows zeego to recognize it when it's mapping children for iOS and Android.

Example

For now, you should reference the example in the repo.

I also added a Moti + Dripsy example.

In the future, I'll make an example app with Solito too.

const DropdownMenuExample = () => {
  const [bookmarked, setBookmarked] = useState<'on' | 'off' | 'mixed'>('on')
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>
        <View>
          <Text style={styles.button}>{`<DropdownMenu />`}</Text>
        </View>
      </DropdownMenu.Trigger>
      <DropdownMenu.Content style={dropdownStyles.content}>
        <DropdownMenuLabel>Help</DropdownMenuLabel>
        <DropdownMenuItem
          style={dropdownStyles.item}
          onSelect={select(1)}
          key="first"
        >
          <DropdownMenuItemTitle style={dropdownStyles.itemTitle}>
            See more
          </DropdownMenuItemTitle>
          {Platform.OS === 'ios' && (
            <DropdownMenu.ItemSubtitle style={dropdownStyles.itemSubtitle}>
              12 artists fit your search
            </DropdownMenu.ItemSubtitle>
          )}
          <DropdownMenuItemIcon
            iosIconName="list.star"
            androidIconName="star_on"
          >
            <Ionicons name="list" size={15} />
          </DropdownMenuItemIcon>
        </DropdownMenuItem>
        <DropdownMenuItem
          style={dropdownStyles.item}
          onSelect={select(2)}
          key="second"
        >
          <DropdownMenuItemTitle>Favorite</DropdownMenuItemTitle>
          <DropdownMenuItemIcon
            iosIconName="star.fill"
            androidIconName="star_off"
          >
            <Ionicons name="star" size={15} />
          </DropdownMenuItemIcon>
        </DropdownMenuItem>
        <DropdownMenuCheckboxItem
          style={dropdownStyles.item}
          value={bookmarked}
          onValueChange={setBookmarked}
          key="third"
        >
          <DropdownMenuItemIndicator>
            <Ionicons name="checkmark" size={19} />
          </DropdownMenuItemIndicator>
          <DropdownMenuItemTitle>
            {bookmarked === 'on' ? 'Bookmarked' : 'Bookmark'}
          </DropdownMenuItemTitle>
          <DropdownMenuItemImage
            iosIconName="book"
            source={require('./camera-outline.png')}
            width={20}
            resizeMode="contain"
          />
        </DropdownMenuCheckboxItem>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  )
}

TODO

  • zeego/dropdown-menu
  • zeego/context-menu (in-progress, missing Web implementation)
  • Android native implementation
  • Docs
  • zeego/tooltip (probably?)
  • zeego/popover (probably)

Thanks

Special thanks to Dominic Go for the awesome iOS context menu. Also, thanks to the Showtime team for testing this and sending PRs.

About

Menus for React (Native) done right.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 99.2%
  • Other 0.8%