React Native · NativeWind

Origin App — Widget Gallery

Menu ordering components. Live demos use web counterparts; native code shown alongside.

StoreHeader

_components/store-header.tsx

Default

Ordered 3 timesGet 1 Buy 1 Free

Service fee will be applied to all orders

<View className="px-4 py-3">
  <Text className="text-xl font-bold">{storeInfo.name}</Text>
  <Text className="text-xs text-muted-foreground">
    {storeInfo.address} · {storeInfo.distance}
  </Text>
  <View className="flex-row flex-wrap gap-1.5 mt-2">
    {storeInfo.promos.map(p => (
      <Badge key={p} variant="secondary">{p}</Badge>
    ))}
  </View>
</View>

OrderTypeBar

_components/order-type-bar.tsx

Pickup active

Powered by DOORDASH

Delivery active

Powered by DOORDASH

<View className="flex-row gap-2 px-4 py-2">
  {orderTypes.map(t => (
    <Pressable
      key={t.id}
      className={cn(
        "flex-1 items-center gap-1 rounded-lg py-2",
        isActive ? "bg-foreground" : "border border-border"
      )}
    >
      <t.icon className={cn("h-4 w-4", isActive ? "text-background" : "text-muted-foreground")} />
      <Text className={cn("text-[10px] font-medium", isActive ? "text-background" : "text-muted-foreground")}>
        {t.label}
      </Text>
    </Pressable>
  ))}
</View>

StoreSelector

_components/store-selector.tsx

Flaming Grill active

<ScrollView horizontal className="flex-row gap-2 px-4 py-2">
  {stores.map(s => (
    <Pressable
      key={s.id}
      className={cn(
        "rounded-full px-4 py-1.5",
        selected === s.id ? "bg-foreground" : "bg-muted"
      )}
    >
      <Text className={cn("text-xs font-medium", selected === s.id ? "text-background" : "text-muted-foreground")}>
        {s.name}
      </Text>
    </Pressable>
  ))}
</ScrollView>

CategoryTabs

_components/category-tabs.tsx

Default

<View className="flex-row items-center gap-2 border-b px-4 py-2">
  <Search className="h-4 w-4 text-muted-foreground" />
  <ScrollView horizontal className="flex-row gap-4">
    {categories.map((cat, i) => (
      <Pressable key={cat} onPress={() => setSelected(i)}>
        <Text className={cn("text-sm", selected === i ? "font-bold" : "text-muted-foreground")}>
          {cat}
        </Text>
      </Pressable>
    ))}
  </ScrollView>
</View>

MenuItemCard

_components/menu-item-card.tsx

No quantity (add button)

Teriyaki Chicken

Grilled chicken with teriyaki sauce

NEWCold 22oz $J

$6.55

With quantity

Beef Bowl

Premium beef with rice

TOP PICKCold 22oz $J

$6.55

2

COMBO tag

Spicy Ramen

Dish Summary or extra tex

COMBOCold 22oz $J

$6.55

<View className="flex-row gap-3 px-4 py-3">
  <Image source={item.image} className="h-20 w-20 rounded-lg bg-muted" />
  <View className="flex-1 justify-between">
    <Text className="text-sm font-semibold">{item.name}</Text>
    <Text className="text-xs text-muted-foreground" numberOfLines={1}>{item.description}</Text>
    <View className="flex-row flex-wrap gap-1 mt-1">
      {item.tags.map(tag => <TagBadge key={tag} tag={tag} />)}
    </View>
    <Text className="text-sm font-semibold mt-1">${item.price.toFixed(2)}</Text>
  </View>
  {/* Add / QuantityStepper */}
</View>

CartBar

_components/cart-bar.tsx

With items

$9.90$13.10
<View className="flex-row items-center justify-between border-t px-4 py-3">
  <View className="flex-row items-center gap-2">
    <ShoppingCart className="h-5 w-5" />
    <Text className="text-base font-bold">${total.toFixed(2)}</Text>
    <Text className="text-xs text-muted-foreground line-through">${originalTotal.toFixed(2)}</Text>
  </View>
  <Pressable className="rounded-full bg-destructive px-6 py-2">
    <Text className="text-sm font-semibold text-destructive-foreground">Checkout</Text>
  </Pressable>
</View>

BottomNav

_components/bottom-nav.tsx

Order tab active

<View className="flex-row border-t">
  {tabs.map(t => (
    <Pressable key={t.id} className="flex-1 items-center gap-0.5 py-2">
      <t.icon className={cn("h-5 w-5", isActive && "fill-current")} />
      <Text className={cn("text-[10px]", isActive ? "font-bold text-foreground" : "text-muted-foreground")}>
        {t.label}
      </Text>
    </Pressable>
  ))}
</View>