SurveyPopover
Floating panel anchored to a DOM element via Floating UI, with automatic flip and shift collision avoidance
SurveyPopover positions a survey panel adjacent to a target element using @floating-ui/react. It renders into a portal and returns null when neither visible nor anchored.
Import
import { SurveyPopover } from '@tour-kit/surveys';Usage
With an element ref
import { useRef } from 'react';
import { SurveyPopover, QuestionRating, useSurvey } from '@tour-kit/surveys';
function FeatureRating() {
const buttonRef = useRef<HTMLButtonElement>(null);
const survey = useSurvey('feature-rating');
return (
<>
<button
ref={buttonRef}
onClick={survey.show}
data-survey-popover-anchor="feature-rating"
>
Rate this feature
</button>
<SurveyPopover
surveyId="feature-rating"
anchor={buttonRef.current}
options={{ position: 'bottom-right', offset: 8 }}
>
<QuestionRating
id="rating"
label="How useful is this feature?"
min={1}
max={5}
style="stars"
onChange={(value) => {
survey.answer('rating', value);
survey.complete();
}}
/>
</SurveyPopover>
</>
);
}With a CSS selector
<SurveyPopover
surveyId="feature-rating"
anchorSelector="#rate-button"
options={{ position: 'top-right' }}
>
{/* content */}
</SurveyPopover>Auto anchor via data attribute
If neither anchor nor anchorSelector is provided, the popover looks for [data-survey-popover-anchor="<surveyId>"] in the document.
Props
Prop
Type
PopoverOptions
Prop
Type
The popover renders null if the survey is visible but no anchor can be resolved (no anchor
prop, no anchorSelector match, and no [data-survey-popover-anchor] element). Ensure the
anchor element is in the DOM before calling survey.show().
Collision avoidance
The popover uses Floating UI middleware in order: offset → flip → shift({ padding: 8 }). The panel will flip to the opposite side if the preferred placement overflows the viewport, and will shift along the axis to keep within the viewport with 8px of padding.