@sensefolks/fastpoll
v1.1.0
Published
Conduct single or multi-choice polls to understand user opinions in a snap
Maintainers
Readme
sf-fastpoll
Fast poll survey web component for collecting user feedback with single/multiple choice options.
Features
- 🎯 Single and multiple choice polls
- 📝 Optional follow-up questions (triggered by specific choices)
- 👤 Optional respondent details collection (text, email, number, dropdown, radio, checkbox)
- ♿ Keyboard navigable with ARIA labels and live regions
- 🎨 Customizable via CSS Parts
- 📱 Responsive design
- 🌐 Works with any framework
Installation
NPM
npm install @sensefolks/fastpollCDN (Script Tag)
<!-- Modern browsers (ES modules) -->
<script type="module" src="https://unpkg.com/@sensefolks/fastpoll/dist/sf-fastpoll/sf-fastpoll.esm.js"></script>
<!-- Legacy browsers -->
<script nomodule src="https://unpkg.com/@sensefolks/fastpoll/dist/sf-fastpoll/sf-fastpoll.js"></script>Or via jsDelivr:
<script type="module" src="https://cdn.jsdelivr.net/npm/@sensefolks/fastpoll/dist/sf-fastpoll/sf-fastpoll.esm.js"></script>Usage
HTML
<sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you for your feedback!"></sf-fastpoll>React
import '@sensefolks/fastpoll';
function App() {
return <sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you!"></sf-fastpoll>;
}Vue
<template>
<sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you!"></sf-fastpoll>
</template>
<script>
import '@sensefolks/fastpoll';
export default { name: 'App' };
</script>Angular
// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@sensefolks/fastpoll';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}<!-- component.html -->
<sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you!"></sf-fastpoll>API
Properties
| Property | Attribute | Type | Default | Description |
| ------------------- | -------------------- | --------- | -------------------------------- | --------------------------------------------------------------- |
| surveyKey | survey-key | string | — | UUID of the survey to load (required) |
| completionMessage | completion-message | string | 'Thank you for your response!' | Message shown after successful submission |
| enableEvents | enable-events | boolean | true | Whether to emit custom events (sfReady, sfStepChange, etc.) |
Events
All events are emitted when enableEvents is true (the default).
| Event | Detail | Description |
| ---------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| sfReady | { surveyKey, question, choiceType, choiceCount } | Survey loaded and ready to display |
| sfStepChange | { surveyKey, previousStep, currentStep, currentStepIndex } | User navigated between steps |
| sfChoiceSelect | { surveyKey, selectedChoices, choiceType, lastAction, lastChoice } | User selected or deselected a choice |
| sfSubmit | { surveyKey, selectedChoices, followUpResponse, completionTimeSeconds } | Survey successfully submitted |
| sfError | { surveyKey, errorType, errorMessage } | Error occurred (errorType: 'load', 'submit', or 'validation') |
Survey Steps
The component progresses through steps based on the survey configuration:
- Poll — User selects choices (always shown)
- Follow-up — Free-text response (shown only when selected choices match configured trigger choices)
- Respondent details — Collects user info like name, email, etc. (shown only when configured)
- Completion — Displays the completion message
CSS Parts
Style the component externally using ::part():
/* Layout */
sf-fastpoll::part(survey-container) {
} /* Main wrapper */
sf-fastpoll::part(step) {
} /* Any step container */
sf-fastpoll::part(poll-step) {
} /* Poll step */
sf-fastpoll::part(follow-up-step) {
} /* Follow-up step */
sf-fastpoll::part(respondent-details-step) {
} /* Respondent details step */
sf-fastpoll::part(completion-step) {
} /* Completion step */
sf-fastpoll::part(button-container) {
} /* Button row wrapper */
/* Headings */
sf-fastpoll::part(heading) {
} /* All step headings */
sf-fastpoll::part(poll-heading) {
}
sf-fastpoll::part(follow-up-heading) {
}
sf-fastpoll::part(respondent-details-heading) {
}
sf-fastpoll::part(completion-heading) {
}
/* Poll choices */
sf-fastpoll::part(choices-container) {
} /* Choices wrapper */
sf-fastpoll::part(choice-option) {
} /* Individual choice label */
sf-fastpoll::part(choice-label) {
} /* Choice text span */
/* Buttons */
sf-fastpoll::part(button) {
} /* All buttons */
sf-fastpoll::part(next-button) {
} /* Next / Submit on poll & follow-up */
sf-fastpoll::part(back-button) {
} /* Back button */
sf-fastpoll::part(submit-button) {
} /* Submit on respondent details */
sf-fastpoll::part(retry-button) {
} /* Retry on error */
/* Follow-up */
sf-fastpoll::part(followup-input-container) {
}
sf-fastpoll::part(textarea) {
}
sf-fastpoll::part(followup-textarea) {
}
/* Respondent details form */
sf-fastpoll::part(form-container) {
}
sf-fastpoll::part(form-field) {
}
sf-fastpoll::part(form-label) {
}
sf-fastpoll::part(required-indicator) {
}
sf-fastpoll::part(input) {
}
sf-fastpoll::part(form-input) {
}
sf-fastpoll::part(select) {
}
sf-fastpoll::part(form-select) {
}
sf-fastpoll::part(radio-group) {
}
sf-fastpoll::part(radio-option) {
}
sf-fastpoll::part(radio-input) {
}
sf-fastpoll::part(radio-label) {
}
sf-fastpoll::part(checkbox-group) {
}
sf-fastpoll::part(checkbox-option) {
}
sf-fastpoll::part(checkbox-input) {
}
sf-fastpoll::part(checkbox-label) {
}
/* Messages */
sf-fastpoll::part(message) {
} /* All messages (loading, error) */
sf-fastpoll::part(loading-message) {
}
sf-fastpoll::part(error-message) {
} /* Error text (validation + load/submit) */
sf-fastpoll::part(error-container) {
} /* Error wrapper with retry button */
sf-fastpoll::part(announcements) {
} /* Screen reader live region */Accessibility
- Full keyboard navigation (Tab, Arrow keys, Enter/Space)
- ARIA
role="radiogroup"/role="group"on choices depending on single/multi choice aria-invalidandaria-describedbyon fields with validation errorsaria-live="polite"region for screen reader announcements on step changes and selections- Focus indicators (
outline) on all interactive elements - High contrast mode support via
@media (prefers-contrast: high) - Respects
prefers-reduced-motion
Browser Support
- Chrome 88+
- Firefox 85+
- Safari 14+
- Edge 88+
- IE11 (with ES5 build)
License
MIT © SenseFolks
