11import { useFeatureFlagPayload , useFeatureFlagVariantKey , usePostHog } from '../hooks'
2- import React , { Children , ReactNode , useCallback , useEffect , useRef } from 'react'
2+ import React from 'react'
33import { PostHog } from '../context'
4- import { isFunction , isNull , isUndefined } from '../utils/type-utils'
4+ import { isFunction , isUndefined } from '../utils/type-utils'
5+ import { VisibilityAndClickTrackers } from './internal/VisibilityAndClickTrackers'
56
67export type PostHogFeatureProps = React . HTMLProps < HTMLDivElement > & {
78 flag : string
@@ -25,6 +26,7 @@ export function PostHogFeature({
2526} : PostHogFeatureProps ) : JSX . Element | null {
2627 const payload = useFeatureFlagPayload ( flag )
2728 const variant = useFeatureFlagVariantKey ( flag )
29+ const posthog = usePostHog ( )
2830
2931 const shouldTrackInteraction = trackInteraction ?? true
3032 const shouldTrackView = trackView ?? true
@@ -37,6 +39,8 @@ export function PostHogFeature({
3739 options = { visibilityObserverOptions }
3840 trackInteraction = { shouldTrackInteraction }
3941 trackView = { shouldTrackView }
42+ onInteract = { ( ) => captureFeatureInteraction ( { flag, posthog, flagVariant : variant } ) }
43+ onView = { ( ) => captureFeatureView ( { flag, posthog, flagVariant : variant } ) }
4044 { ...props }
4145 >
4246 { childNode }
@@ -46,7 +50,7 @@ export function PostHogFeature({
4650 return < > { fallback } </ >
4751}
4852
49- function captureFeatureInteraction ( {
53+ export function captureFeatureInteraction ( {
5054 flag,
5155 posthog,
5256 flagVariant,
@@ -65,7 +69,7 @@ function captureFeatureInteraction({
6569 posthog . capture ( '$feature_interaction' , properties )
6670}
6771
68- function captureFeatureView ( {
72+ export function captureFeatureView ( {
6973 flag,
7074 posthog,
7175 flagVariant,
@@ -83,92 +87,3 @@ function captureFeatureView({
8387 }
8488 posthog . capture ( '$feature_view' , properties )
8589}
86-
87- function VisibilityAndClickTracker ( {
88- flag,
89- children,
90- onIntersect,
91- onClick,
92- trackView,
93- options,
94- ...props
95- } : {
96- flag : string
97- children : React . ReactNode
98- onIntersect : ( entry : IntersectionObserverEntry ) => void
99- onClick : ( ) => void
100- trackView : boolean
101- options ?: IntersectionObserverInit
102- } ) : JSX . Element {
103- const ref = useRef < HTMLDivElement > ( null )
104- const posthog = usePostHog ( )
105-
106- useEffect ( ( ) => {
107- if ( isNull ( ref . current ) || ! trackView ) return
108-
109- // eslint-disable-next-line compat/compat
110- const observer = new IntersectionObserver ( ( [ entry ] ) => onIntersect ( entry ) , {
111- threshold : 0.1 ,
112- ...options ,
113- } )
114- observer . observe ( ref . current )
115- return ( ) => observer . disconnect ( )
116- } , [ flag , options , posthog , ref , trackView , onIntersect ] )
117-
118- return (
119- < div ref = { ref } { ...props } onClick = { onClick } >
120- { children }
121- </ div >
122- )
123- }
124-
125- function VisibilityAndClickTrackers ( {
126- flag,
127- children,
128- trackInteraction,
129- trackView,
130- options,
131- ...props
132- } : {
133- flag : string
134- children : React . ReactNode
135- trackInteraction : boolean
136- trackView : boolean
137- options ?: IntersectionObserverInit
138- } ) : JSX . Element {
139- const clickTrackedRef = useRef ( false )
140- const visibilityTrackedRef = useRef ( false )
141- const posthog = usePostHog ( )
142- const variant = useFeatureFlagVariantKey ( flag )
143-
144- const cachedOnClick = useCallback ( ( ) => {
145- if ( ! clickTrackedRef . current && trackInteraction ) {
146- captureFeatureInteraction ( { flag, posthog, flagVariant : variant } )
147- clickTrackedRef . current = true
148- }
149- } , [ flag , posthog , trackInteraction , variant ] )
150-
151- const onIntersect = ( entry : IntersectionObserverEntry ) => {
152- if ( ! visibilityTrackedRef . current && entry . isIntersecting ) {
153- captureFeatureView ( { flag, posthog, flagVariant : variant } )
154- visibilityTrackedRef . current = true
155- }
156- }
157-
158- const trackedChildren = Children . map ( children , ( child : ReactNode ) => {
159- return (
160- < VisibilityAndClickTracker
161- flag = { flag }
162- onClick = { cachedOnClick }
163- onIntersect = { onIntersect }
164- trackView = { trackView }
165- options = { options }
166- { ...props }
167- >
168- { child }
169- </ VisibilityAndClickTracker >
170- )
171- } )
172-
173- return < > { trackedChildren } </ >
174- }
0 commit comments