Generative UI
Feature Voting
Feature request voting list for React and shadcn/ui with upvotes, sorting by vote count, and controlled or uncontrolled state.
Updated
Sorted with vote counts
- API AccessPublic API for third-party integrations
- Mobile AppNative iOS and Android applications
- Dark ModeAdd system-wide dark mode support with automatic detection
- Keyboard ShortcutsCustomizable keyboard shortcuts for power users
- Export to PDFExport documents and reports as PDF files
Basic list
- Dark modeSystem-aware dark theme0
- Keyboard shortcutsCustomizable hotkeys0
Sorted by votes
- Option B5
- Option A2
- Option C1
Feature Voting is a compound React component for shadcn/ui. Use it for public roadmaps, feedback boards, or changelog pages where users rank what to build next.
Installation
pnpm dlx shadcn@latest add @cult-ui/feature-voting
Usage
Use FeatureVoting.Root with FeatureVoting.Item for each feature; each item can include Trigger, Title, Description, and Count. Supports controlled or uncontrolled vote counts and voted-features state, and optional sorting via FeatureVoting.Group.
Basic list
import { FeatureVoting } from "@/registry/default/ui/feature-voting";
export default function Example() {
return (
<FeatureVoting.Root>
<FeatureVoting.Item value="dark-mode">
<FeatureVoting.Title>Dark mode</FeatureVoting.Title>
<FeatureVoting.Description>
System-aware dark theme
</FeatureVoting.Description>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
<FeatureVoting.Item value="keyboard-shortcuts">
<FeatureVoting.Title>Keyboard shortcuts</FeatureVoting.Title>
<FeatureVoting.Description>
Customizable hotkeys
</FeatureVoting.Description>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
</FeatureVoting.Root>
);
}Controlled votes and voted features
Wire value / onValueChange and votedFeatures / onVotedFeaturesChange to sync with your backend or state.
import { useState } from "react";
import { FeatureVoting } from "@/registry/default/ui/feature-voting";
export default function Example() {
const [votes, setVotes] = useState({
"dark-mode": 10,
"keyboard-shortcuts": 5,
});
const [voted, setVoted] = useState(new Set<string>());
return (
<FeatureVoting.Root
value={votes}
onValueChange={setVotes}
votedFeatures={voted}
onVotedFeaturesChange={setVoted}
>
<FeatureVoting.Item value="dark-mode">
<FeatureVoting.Title>Dark mode</FeatureVoting.Title>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
<FeatureVoting.Item value="keyboard-shortcuts">
<FeatureVoting.Title>Keyboard shortcuts</FeatureVoting.Title>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
</FeatureVoting.Root>
);
}With sorting by votes
Wrap items in FeatureVoting.Group with sortBy="votes-desc" or sortBy="votes-asc" to reorder by vote count.
import { FeatureVoting } from "@/registry/default/ui/feature-voting";
export default function Example() {
return (
<FeatureVoting.Root defaultValue={{ a: 2, b: 5, c: 1 }}>
<FeatureVoting.Group sortBy="votes-desc">
<FeatureVoting.Item value="a">
<FeatureVoting.Title>Option A</FeatureVoting.Title>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
<FeatureVoting.Item value="b">
<FeatureVoting.Title>Option B</FeatureVoting.Title>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
<FeatureVoting.Item value="c">
<FeatureVoting.Title>Option C</FeatureVoting.Title>
<FeatureVoting.Count />
<FeatureVoting.Trigger>Vote</FeatureVoting.Trigger>
</FeatureVoting.Item>
</FeatureVoting.Group>
</FeatureVoting.Root>
);
}Features
- Vote and unvote per feature via Trigger; one vote per user per feature (tracked by
votedFeatures) - Controlled or uncontrolled:
value/defaultValueandonValueChangefor vote counts;votedFeatures/defaultVotedFeaturesandonVotedFeaturesChangefor which features the user voted for - Optional sorting:
FeatureVoting.GroupwithsortBy="votes-asc"orsortBy="votes-desc" - Compound API: Root, Group, Item, Trigger, Count, Title, Description
useFeatureVoting()hook for external access to vote state and actions