Feature Poll

Compound feature voting poll for React and shadcn/ui with single or multiple choice, result bars, and keyboard navigation.

Updated

Basic

Which feature matters most?

Pick one option to help us prioritize the roadmap.

With Results

Vote for the next release focus
Results appear after you submit your vote.
118 votes

Multiple Selection

Choose up to 2 priorities
Select the features you want us to focus on next.
118 votes

Feature Poll is a compound React poll component for shadcn/ui. Use it in changelogs, roadmap pages, or in-app surveys to ask users which feature to build next.

Installation

pnpm dlx shadcn@latest add @cult-ui/feature-poll

Usage

Use FeaturePoll.Root with Header, Title, Description, Options (each Option with Indicator and Label), and Footer. Supports single or multiple selection, controlled or uncontrolled value, and optional results after voting.

Basic poll

import { FeaturePoll } from "@/registry/default/ui/feature-poll"; export default function Example() { return ( <FeaturePoll.Root> <FeaturePoll.Header> <FeaturePoll.Title>Which feature matters most?</FeaturePoll.Title> <FeaturePoll.Description> Pick one option. Results are shown after you vote. </FeaturePoll.Description> </FeaturePoll.Header> <FeaturePoll.Options> <FeaturePoll.Option value="speed"> <FeaturePoll.Indicator /> <FeaturePoll.Label>Faster builds</FeaturePoll.Label> </FeaturePoll.Option> <FeaturePoll.Option value="dx"> <FeaturePoll.Indicator /> <FeaturePoll.Label>Better DX</FeaturePoll.Label> </FeaturePoll.Option> <FeaturePoll.Option value="docs"> <FeaturePoll.Indicator /> <FeaturePoll.Label>Clearer docs</FeaturePoll.Label> </FeaturePoll.Option> </FeaturePoll.Options> <FeaturePoll.Footer /> </FeaturePoll.Root> ); }

Poll with results (controlled)

Wire value / onValueChange and set showResults, hasVoted, and votes when the user submits to show results and “You voted”.

import { useState } from "react"; import { FeaturePoll } from "@/registry/default/ui/feature-poll"; export default function Example() { const [value, setValue] = useState<string | undefined>(); const [hasVoted, setHasVoted] = useState(false); const votes = { speed: 42, dx: 28, docs: 30 }; return ( <FeaturePoll.Root value={value} onValueChange={setValue} hasVoted={hasVoted} showResults votes={votes} > <FeaturePoll.Header> <FeaturePoll.Title>Which feature matters most?</FeaturePoll.Title> <FeaturePoll.Description> Pick one, then submit. </FeaturePoll.Description> </FeaturePoll.Header> <FeaturePoll.Options> <FeaturePoll.Option value="speed"> <FeaturePoll.Indicator /> <FeaturePoll.Label>Faster builds</FeaturePoll.Label> <FeaturePoll.Progress /> <FeaturePoll.Percentage /> </FeaturePoll.Option> <FeaturePoll.Option value="dx"> <FeaturePoll.Indicator /> <FeaturePoll.Label>Better DX</FeaturePoll.Label> <FeaturePoll.Progress /> <FeaturePoll.Percentage /> </FeaturePoll.Option> <FeaturePoll.Option value="docs"> <FeaturePoll.Indicator /> <FeaturePoll.Label>Clearer docs</FeaturePoll.Label> <FeaturePoll.Progress /> <FeaturePoll.Percentage /> </FeaturePoll.Option> </FeaturePoll.Options> <FeaturePoll.Footer /> {/* In real usage, a submit button would set hasVoted to true */} </FeaturePoll.Root> ); }

Features

  • Single or multiple selection via multiple
  • Controlled or uncontrolled value via value / defaultValue and onValueChange
  • Optional results: showResults, votes, hasVoted for progress bars and “You voted”
  • Keyboard navigation (Arrow keys, Home, End) in the options list
  • Compound API: Root, Header, Title, Description, Options, Option, Indicator, Label, Progress, Percentage, Footer