React Native Modal Styling
Bubbl provides payloads. Your app owns modal UI and visual system.
Recommended architecture
- Subscribe to
BubblBridge.onNotification - Normalize payload shape (
mediaUrl,mediaType,questions,postMessage) - Render a single modal component for all notification types
- Report analytics (
cta_engagement,media_viewed,dismissed, survey events)
Layout blueprint
Use a layered modal:
- Backdrop: dimmed press-to-dismiss layer
- Card container: rounded surface, constrained width/height
- Scroll content: headline/body/media/survey/actions
- Close affordance: top-right explicit close button
<Modal transparent animationType="fade" visible={visible}>
<View style={styles.overlay}>
<Pressable style={styles.backdrop} onPress={onClose} />
<View style={styles.card}>{/* content */}</View>
</View>
</Modal>
Media rendering strategy
image:ImagewithresizeMode="contain"videooraudio:WebViewor platform player- YouTube: use
youtube-nocookie.com/embed/<id>iframe for cleaner embedding
Survey styling strategy
- Render each question in a card (
border,radius,padding) - Keep primary action fixed/clear (
Submit Survey) - Validate required questions before submit
- Use explicit selected states for choice/radio/checkbox rows
Example style tokens
const styles = StyleSheet.create({
overlay: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 16,
},
backdrop: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.58)',
},
card: {
width: '100%',
maxWidth: 560,
maxHeight: '86%',
backgroundColor: '#fff',
borderRadius: 20,
overflow: 'hidden',
elevation: 12,
},
});
Analytics hooks to keep
When users interact, emit events through bridge methods:
- Survey modal shown:
notification_deliveredandcta_engagement - CTA tap:
ctaortrackSurveyEvent(..., 'cta_engagement') - Media displayed:
trackSurveyEvent(..., 'media_viewed') - Dismissal:
trackSurveyEvent(..., 'dismissed') - Survey submission:
submitSurveyResponse(...)then close modal on success
Accessibility
- Make close button and CTA accessible (
accessibilityRole="button") - Ensure readable contrast for overlay and text
- Keep text scalable and avoid truncating long body copy