# rn-morph-popover URL: /docs/native/components/morph-popover A trigger button that morphs into a floating panel, animated with Reanimated. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-morph-popover ``` **Dependencies:** - [react-native-reanimated](https://www.npmjs.com/package/react-native-reanimated) The trigger is measured with `measureInWindow`. A transparent `Modal` then shows a panel that starts at the trigger's size and corner radius and grows to the content size, while the content fades and slides in. Closing plays the animation in reverse. Tapping outside the panel closes it. The panel opens on `side` and flips to the other side when there is not enough room. It is centred on the trigger and kept 16pt from the screen edges. If the content changes height while open, the panel resizes in place. When the system's reduce-motion setting is on, the panel appears without animation. ## Usage ```tsx import { MorphPopover } from '@/components/docyrus-native/morph-popover'; ``` ```tsx }> ``` Content text does not inherit colour on React Native, so style the children to contrast with `bgClassName`. The default background is `bg-neutral-900` in light mode and `bg-neutral-100` in dark mode. ## API Reference | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `ReactNode` | - | Panel content (required) | | `trigger` | `ReactNode` | - | Trigger content (default: a plus icon) | | `triggerSize` | `number` | `44` | Square trigger size (px) | | `triggerWidth` | `number` | - | Trigger width (overrides triggerSize) | | `triggerHeight` | `number` | - | Trigger height (overrides triggerSize) | | `triggerRadius` | `number` | `triggerSize / 2 (6 with custom dimensions)` | Trigger corner radius | | `triggerClassName` | `string` | - | Trigger classes | | `disabled` | `boolean` | `false` | Disables the trigger | | `isOpen` | `boolean` | - | Controlled open state | | `onOpenChange` | `(open: boolean) => void` | - | Open state change callback | | `side` | `'top' \| 'bottom'` | `'top'` | Preferred side; flips when there is not enough room | | `sideOffset` | `number` | `24` | Gap between trigger and panel (px) | | `contentWidth` | `number` | `240` | Panel width, clamped to screen width minus a 16pt gutter | | `speed` | `number` | `0.25` | Animation duration in seconds | | `bgClassName` | `string` | `'bg-neutral-900 dark:bg-neutral-100'` | Background classes shared by trigger and panel | | `contentClassName` | `string` | - | Panel content classes | | `className` | `string` | - | Wrapper classes | ## Type Exports | Type | Description | |------|-------------| | `MorphPopoverProps` | Props for `MorphPopover` | ## Differences from web - GSAP is replaced by Reanimated. The SVG "goo" filter has no React Native equivalent and is not reproduced. - `speed` is still in seconds. - Outside clicks and Escape become a backdrop tap and the Android back button.