-
Couldn't load subscription status.
- Fork 54
Description
Summary
Right now, the only way to mask content in React Native session replays (via @amplitude/plugin-session-replay-react-native) is to wrap said content into a <MaskView /> component. This unnecessarily adds extra layouts to the resulting UI (even if they're "hdden") which is not just overkill but also breaks non-block layouts. (See in-line layouts below.)
My request is to add support for an attribute like amplitude-mask={"mask"} or amplitude-mask={"unmask"} that can be applied to ANY element and has the same impact as wrapping said component in <MaskView/ >. If this is too complicated, could we at least provide a way to pass it to a <Text /> or <TextInput /> component, for example by introducing a <MaskedText /> and <MaskedTextInput /> component?
This is especially useful for privacy-critical applications where all text should be masked by default, with an explicit prop that whitelists (unmasks) safe content like titles, buttons and navigation items.
Motivations
React Native has two distinct and incompatible layout systems:
- Block Layout (e.g. for
<View>and<Pressable />): They use Flexbox for layout and do not allow inline flow. - Inline Layout (e.g. for
<Text>): A<Text>component can contain nested child<Text>components. These children will flow together inline on the same line and inherit text styles from their parent. This is essential for building any kind of formatted text.
Wrapping a <Text> component inside a <View> (which a <MaskView> would do) breaks the inline text layout model. Yes, one can wrap the top-level text component with it, but this doesn't allow a whitelist-only approach where by default all <Text /> elements are masked and only select ones are unmasked.
This change would make this package ready for privacy-focused Production apps and (IMO) bridge the gap to Sentry, PostHog and UXCam. Thanks for the consideration! 🙏