Skip to content

Commit ce8ec90

Browse files
fix: dont propagate events in surveys (#1911)
1 parent d51283d commit ce8ec90

File tree

2 files changed

+89
-7
lines changed

2 files changed

+89
-7
lines changed

src/__tests__/extensions/surveys/question-types.test.tsx

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { fireEvent, render } from '@testing-library/preact'
2-
import { MultipleChoiceQuestion } from '../../../extensions/surveys/components/QuestionTypes'
3-
import { MultipleSurveyQuestion, SurveyQuestionType } from '../../../posthog-surveys-types'
2+
import { MultipleChoiceQuestion, OpenTextQuestion } from '../../../extensions/surveys/components/QuestionTypes'
3+
import { BasicSurveyQuestion, MultipleSurveyQuestion, SurveyQuestionType } from '../../../posthog-surveys-types'
44

55
describe('MultipleChoiceQuestion', () => {
66
const mockAppearance = {
@@ -141,5 +141,73 @@ describe('MultipleChoiceQuestion', () => {
141141
expect(document.activeElement).toBe(openInput)
142142
}, 0)
143143
})
144+
145+
it('does not propagate keydown events from open choice input', () => {
146+
const parentKeyDownHandler = jest.fn()
147+
const { container } = render(
148+
<div onKeyDown={parentKeyDownHandler}>
149+
<MultipleChoiceQuestion {...baseProps} question={multipleChoiceQuestion} />
150+
</div>
151+
)
152+
153+
// Find the open-ended input using its specific ID
154+
const openInput = container.querySelector('#surveyQuestion1Choice3Open') as HTMLInputElement
155+
if (!openInput) {
156+
throw new Error('Open choice input not found')
157+
}
158+
159+
// Simulate typing 'C' into the open-ended input
160+
fireEvent.keyDown(openInput, { key: 'C', code: 'KeyC' })
161+
162+
// Assert that the parent's keydown handler was NOT called
163+
expect(parentKeyDownHandler).not.toHaveBeenCalled()
164+
})
144165
})
145166
})
167+
168+
describe('OpenTextQuestion', () => {
169+
const mockAppearance = {
170+
backgroundColor: '#fff',
171+
submitButtonText: 'Submit',
172+
placeholder: 'Enter your response',
173+
}
174+
175+
const baseProps = {
176+
forceDisableHtml: false,
177+
appearance: mockAppearance,
178+
onSubmit: jest.fn(),
179+
onPreviewSubmit: jest.fn(),
180+
}
181+
182+
const openTextQuestion: BasicSurveyQuestion = {
183+
type: SurveyQuestionType.Open,
184+
question: 'What is your feedback?',
185+
description: 'Provide details below',
186+
optional: false,
187+
}
188+
189+
it('does not propagate keydown events', () => {
190+
const parentKeyDownHandler = jest.fn()
191+
192+
// Render the component within a div that has a keydown listener
193+
const { container } = render(
194+
<div onKeyDown={parentKeyDownHandler}>
195+
<OpenTextQuestion {...baseProps} question={openTextQuestion} />
196+
</div>
197+
)
198+
199+
const textarea = container.querySelector('textarea')
200+
201+
if (!textarea) {
202+
throw new Error('Textarea not found')
203+
}
204+
205+
// Simulate typing 'C' into the textarea
206+
fireEvent.keyDown(textarea, { key: 'C', code: 'KeyC' })
207+
208+
// Assert that the parent's keydown handler was NOT called
209+
expect(parentKeyDownHandler).not.toHaveBeenCalled()
210+
})
211+
212+
// Add other tests for OpenTextQuestion if needed...
213+
})

src/extensions/surveys/components/QuestionTypes.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,17 @@ export function OpenTextQuestion({
4949
backgroundColor={appearance.backgroundColor}
5050
forceDisableHtml={forceDisableHtml}
5151
/>
52-
<textarea rows={4} placeholder={appearance?.placeholder} onInput={(e) => setText(e.currentTarget.value)} />
52+
<textarea
53+
rows={4}
54+
placeholder={appearance?.placeholder}
55+
onInput={(e) => {
56+
setText(e.currentTarget.value)
57+
e.stopPropagation()
58+
}}
59+
onKeyDown={(e) => {
60+
e.stopPropagation()
61+
}}
62+
/>
5363
<BottomSection
5464
text={question.buttonText || 'Submit'}
5565
submitDisabled={!text && !question.optional}
@@ -291,10 +301,11 @@ export function MultipleChoiceQuestion({
291301
}
292302
}
293303

294-
const handleOpenEndedInputChange = (value: string) => {
295-
setOpenEndedInput(value)
304+
const handleOpenEndedInputChange = (e: React.FormEvent<HTMLInputElement>) => {
305+
e.stopPropagation()
306+
setOpenEndedInput(e.currentTarget.value)
296307
if (question.type === SurveyQuestionType.SingleChoice) {
297-
setSelectedChoices(value)
308+
setSelectedChoices(e.currentTarget.value)
298309
}
299310
}
300311

@@ -340,7 +351,10 @@ export function MultipleChoiceQuestion({
340351
id={`surveyQuestion${displayQuestionIndex}Choice${idx}Open`}
341352
name={`question${displayQuestionIndex}`}
342353
value={openEndedInput}
343-
onInput={(e) => handleOpenEndedInputChange(e.currentTarget.value)}
354+
onKeyDown={(e) => {
355+
e.stopPropagation()
356+
}}
357+
onInput={(e) => handleOpenEndedInputChange(e)}
344358
onClick={(e) => {
345359
// Ensure the checkbox/radio gets checked when clicking the input
346360
if (!openChoiceSelected) {

0 commit comments

Comments
 (0)