Bloom MenuAndroid
FAB that blooms into a radial fan of action buttons — Material's speed-dial idiom.
$ npx lumioui add bloom-menu
import { BloomMenu } from "@/components/ui/bloom-menu/bloom-menu";
Files installed into your repo
components/ui/bloom-menu/bloom-menu.tsx
Native packages required
@lumioui/core@latestreact-native-reanimated@*
Props11
| actions | BloomMenuAction[] | The actions that bloom out when the FAB is pressed. |
| open? | boolean | Controlled open state. Omit + use defaultOpen for uncontrolled. |
| defaultOpen? | boolean | Uncontrolled initial open state. |
| onOpenChange? | (open: boolean) => void | |
| icon? | IconName | FAB icon. Default "plus". |
| closeIcon? | IconName | Icon when open — defaults to the same icon rotated 45°. Pass "x" for an explicit close glyph. |
| direction? | "up" | "down" | Fan direction. "up" stacks actions above the FAB (default, matches Material's speed-dial). "down" stacks them below. |
| backdrop? | boolean | Show a scrim behind the open menu. Default true. |
| haptic? | boolean | Haptic on open/close and action press. Default true. |
| accessibilityLabel? | string | a11y label for the FAB. Default "Open actions". |
| className? | string | |
Bloom Menufab-actions.tsx
Live preview offline the relay is unreachable — check back shortly
bloom-menu/variants/fab-actions.tsx open FAB that blooms into a radial fan of action buttons — Material's speed-dial idiom.
import { BloomMenuFabActions } from "@/components/ui/bloom-menu/variants/fab-actions";
export function Example() {
return (
<BloomMenuFabActions />
);
}
import * as React from "react";
import { View } from "react-native";
import { BloomMenu } from "../bloom-menu";
import { Glass } from "../../glass/glass";
import { Text } from "../../text/text";
/** BloomMenuFabActions — speed-dial blooming over a glass chat surface. */
export function BloomMenuFabActions() {
const [last, setLast] = React.useState("Driver 4 stops away");
const act = (label: string) => () => setLast(`Sent to Diego — ${label.toLowerCase()}`);
return (
<View className="w-full gap-3">
<Glass interactive curvature="edge" className="w-full gap-3 rounded-2xl p-4">
<View className="gap-0.5">
<Text variant="small" className="font-semibold">Diego Ruiz · Order #8421</Text>
<Text variant="muted">Delivery chat — actions bloom from the corner</Text>
</View>
<Glass interactive curvature="edge" className="relative h-56 w-full overflow-hidden rounded-xl p-3">
<View className="gap-2">
<Glass interactive curvature="edge" className="max-w-[78%] self-start rounded-2xl rounded-bl-md px-3 py-2">
<Text className="text-sm leading-tight text-foreground">Hey, is the order still arriving at 2 pm?</Text>
</Glass>
<View className="max-w-[78%] self-end rounded-2xl rounded-br-md bg-primary px-3 py-2">
<Text className="text-sm leading-tight text-primary-foreground">Yes — driver's 4 stops away</Text>
</View>
<Glass interactive curvature="edge" className="max-w-[78%] self-start rounded-2xl rounded-bl-md px-3 py-2">
<Text className="text-sm leading-tight text-foreground">Perfect, thanks!</Text>
</Glass>
</View>
<View className="absolute bottom-3 right-3">
<BloomMenu
actions={[
{ icon: "edit", label: "Message", onPress: act("Message") },
{ icon: "phone", label: "Call", onPress: act("Call") },
{ icon: "image", label: "Photo", onPress: act("Photo") },
]}
backdrop={false}
/>
</View>
</Glass>
<Text variant="muted">{last}</Text>
</Glass>
</View>
);
}