diff --git a/packages/browser/package.json b/packages/browser/package.json
index a861661d66..d7a22cde46 100644
--- a/packages/browser/package.json
+++ b/packages/browser/package.json
@@ -85,7 +85,6 @@
"@types/dotenv": "^8.2.3",
"@types/jest": "^29.5.12",
"@types/node": "^22.5.0",
- "@types/react-dom": "^18.0.10",
"@types/sinon": "^17.0.1",
"@types/web": "^0.0.222",
"babel-jest": "^29.7.0",
diff --git a/packages/browser/src/extensions/surveys.tsx b/packages/browser/src/extensions/surveys.tsx
index 8d8597dbe1..bee3d3f3a3 100644
--- a/packages/browser/src/extensions/surveys.tsx
+++ b/packages/browser/src/extensions/surveys.tsx
@@ -1,4 +1,4 @@
-import * as Preact from 'preact'
+import { type JSX, type RefObject, render, Fragment } from 'preact'
import { useContext, useEffect, useMemo, useRef, useState } from 'preact/hooks'
import { PostHog } from '../posthog-core'
import {
@@ -185,7 +185,7 @@ const SURVEY_NEXT_TO_TRIGGER_PARAMS = {
TRIGGER_SPACING: 12,
} as const
-function getNextToTriggerPosition(target: HTMLElement, surveyWidth: number): React.CSSProperties | null {
+function getNextToTriggerPosition(target: HTMLElement, surveyWidth: number): JSX.CSSProperties | null {
try {
const buttonRect = target.getBoundingClientRect()
const viewportHeight = window.innerHeight
@@ -212,7 +212,7 @@ function getNextToTriggerPosition(target: HTMLElement, surveyWidth: number): Rea
right: 'auto',
bottom: showAbove ? `${viewportHeight - buttonRect.top + spacing}px` : 'auto',
zIndex: defaultSurveyAppearance.zIndex,
- } satisfies React.CSSProperties
+ } satisfies JSX.CSSProperties
} catch (error) {
logger.warn('Failed to calculate trigger position:', error)
return null
@@ -270,7 +270,7 @@ export class SurveyManager {
const delaySeconds = survey.appearance?.surveyPopupDelaySeconds || 0
const { shadow } = retrieveSurveyShadow(survey, this._posthog)
if (delaySeconds <= 0) {
- return Preact.render(
+ return render(
, shadow)
+ render(, shadow)
}
private _removeWidgetSelectorListener = (survey: Pick): void => {
@@ -406,7 +406,7 @@ export class SurveyManager {
public renderPopover = (survey: Survey): void => {
const { shadow } = retrieveSurveyShadow(survey, this._posthog)
- Preact.render(
+ render(
,
shadow
)
@@ -417,7 +417,7 @@ export class SurveyManager {
this._handleUrlPrefill(survey)
}
- Preact.render(
+ render(
void
posthog?: PostHog
- positionStyles?: React.CSSProperties
+ positionStyles?: JSX.CSSProperties
}) => {
const currentStyle = parentElement.querySelector('style[data-ph-survey-style]')
if (currentStyle) {
@@ -737,7 +737,7 @@ export const renderSurveysPreview = ({
parentElement.appendChild(stylesheet)
addSurveyCSSVariablesToElement(parentElement, survey.type, survey.appearance)
}
- Preact.render(
+ render(
, root)
+ render(, root)
}
// This is the main exported function
@@ -904,7 +904,7 @@ export function usePopupVisibility(
isPreviewMode: boolean,
removeSurveyFromFocus: (survey: SurveyWithTypeAndAppearance) => void,
isPopup: boolean,
- surveyContainerRef?: React.RefObject
+ surveyContainerRef?: RefObject
) {
const [isPopupVisible, setIsPopupVisible] = useState(
isPreviewMode || millisecondDelay === 0 || survey.type === SurveyType.ExternalSurvey
@@ -1019,7 +1019,7 @@ interface SurveyPopupProps {
survey: Survey
forceDisableHtml?: boolean
posthog?: PostHog
- style?: React.CSSProperties
+ style?: JSX.CSSProperties
previewPageIndex?: number | undefined
removeSurveyFromFocus?: (survey: SurveyWithTypeAndAppearance) => void
isPopup?: boolean
@@ -1063,7 +1063,7 @@ function getPopoverPosition(
}
}
-function getTabPositionStyles(position: SurveyTabPosition = SurveyTabPosition.Right): React.CSSProperties {
+function getTabPositionStyles(position: SurveyTabPosition = SurveyTabPosition.Right): JSX.CSSProperties {
switch (position) {
case SurveyTabPosition.Top:
return { top: '0', left: '50%', transform: 'translateX(-50%)' }
@@ -1293,7 +1293,7 @@ export function FeedbackWidget({
}): JSX.Element | null {
const [isFeedbackButtonVisible, setIsFeedbackButtonVisible] = useState(true)
const [showSurvey, setShowSurvey] = useState(false)
- const [styleOverrides, setStyleOverrides] = useState({})
+ const [styleOverrides, setStyleOverrides] = useState({})
const toggleSurvey = () => {
setShowSurvey(!showSurvey)
@@ -1360,7 +1360,7 @@ export function FeedbackWidget({
}
return (
-
+
{survey.appearance?.widgetType === 'tab' && (
)}
-
+
)
}
diff --git a/packages/browser/src/extensions/surveys/components/QuestionTypes.tsx b/packages/browser/src/extensions/surveys/components/QuestionTypes.tsx
index 3dfcdcf789..e0fa7b82d1 100644
--- a/packages/browser/src/extensions/surveys/components/QuestionTypes.tsx
+++ b/packages/browser/src/extensions/surveys/components/QuestionTypes.tsx
@@ -1,4 +1,4 @@
-import { Fragment } from 'preact'
+import { Fragment, type JSX } from 'preact'
import { useEffect, useMemo, useRef, useState } from 'preact/hooks'
import {
BasicSurveyQuestion,
@@ -368,7 +368,7 @@ export function MultipleChoiceQuestion({
}
}
- const handleOpenEndedInputChange = (e: React.FormEvent) => {
+ const handleOpenEndedInputChange = (e: JSX.TargetedEvent) => {
e.stopPropagation()
const newValue = e.currentTarget.value
@@ -382,7 +382,7 @@ export function MultipleChoiceQuestion({
}
}
- const handleOpenEndedKeyDown = (e: React.KeyboardEvent) => {
+ const handleOpenEndedKeyDown = (e: JSX.TargetedKeyboardEvent) => {
e.stopPropagation()
// Handle Enter key to submit form if valid
diff --git a/packages/browser/src/extensions/surveys/surveys-extension-utils.tsx b/packages/browser/src/extensions/surveys/surveys-extension-utils.tsx
index 44d57d307b..41d6da8daf 100644
--- a/packages/browser/src/extensions/surveys/surveys-extension-utils.tsx
+++ b/packages/browser/src/extensions/surveys/surveys-extension-utils.tsx
@@ -1,4 +1,4 @@
-import { VNode, cloneElement, createContext } from 'preact'
+import { VNode, cloneElement, createContext, type JSX } from 'preact'
import { PostHog } from '../../posthog-core'
import {
MultipleSurveyQuestion,
@@ -585,7 +585,7 @@ interface RenderProps {
component: VNode<{ className: string }>
children: string
renderAsHtml?: boolean
- style?: React.CSSProperties
+ style?: JSX.CSSProperties
}
export const renderChildrenAsTextOrHtml = ({ component, children, renderAsHtml, style }: RenderProps) => {
diff --git a/packages/browser/tsconfig.json b/packages/browser/tsconfig.json
index a5dc7e13c5..4ec45144bc 100644
--- a/packages/browser/tsconfig.json
+++ b/packages/browser/tsconfig.json
@@ -20,9 +20,8 @@
"resolveJsonModule": true,
"downlevelIteration": true,
"declaration": true,
- "jsx": "preserve",
- "jsxFactory": "h",
- "jsxFragmentFactory": "Fragment"
+ "jsx": "react-jsx",
+ "jsxImportSource": "preact"
},
"include": ["./src/**/*.ts*"],
"exclude": ["./src/__tests__/**/*.ts*"]
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f707c76656..d8bab603b0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -288,9 +288,6 @@ importers:
'@types/node':
specifier: ^22.5.0
version: 22.5.0
- '@types/react-dom':
- specifier: ^18.0.10
- version: 18.0.10
'@types/sinon':
specifier: ^17.0.1
version: 17.0.1
@@ -4072,9 +4069,6 @@ packages:
'@types/range-parser@1.2.7':
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
- '@types/react-dom@18.0.10':
- resolution: {integrity: sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==}
-
'@types/react-native@0.69.26':
resolution: {integrity: sha512-K11OWz8SU3Eill/EUhma54qOeczUjIhTlV1Luv2BODawPsM8nCVJkWaAUCqJaMFrcIKUTH0KIYUzUjqWlRUNfw==}
@@ -18598,10 +18592,6 @@ snapshots:
'@types/range-parser@1.2.7': {}
- '@types/react-dom@18.0.10':
- dependencies:
- '@types/react': 17.0.87
-
'@types/react-native@0.69.26':
dependencies:
'@types/react': 17.0.87