SDK UI component
Add a feature request screen with React Native, SwiftUI, Flutter, Android Compose or .NET MAUI.
Basic usage
Install and configure the SDK first. Every React Native example below must render inside a FeaturamaProvider configured with a project key and the matching API origin; see SDK setup. The screen does not accept an API key directly.
Flutter, Swift, Android and .NET MAUI examples here target the local source previews described in SDK setup. These changes are being prepared locally for publication; they have not been published. Configure Swift, Android and MAUI before constructing their screens. Flutter takes a configured client and leaves its lifetime to the host app. Pair the project key with its issuing API origin. The SDK does not migrate the project or fall back to another origin.
import { FeatureRequestsScreen } from '@vibelabsdotto/featurama-rn-expo';
import { useColorScheme } from 'react-native';
function FeedbackScreen({ onClose }: { onClose: () => void }) {
const colorScheme = useColorScheme() ?? 'light';
return (
<FeatureRequestsScreen
colorScheme={colorScheme}
accentColor="#6366f1"
onClose={onClose}
/>
);
}Props
FeatureRequestsScreen for React Native
| Prop | Type | Required | Description |
|---|---|---|---|
colorScheme | 'light' | 'dark' | Yes | Controls light/dark theme |
accentColor | string | Yes | Hex color for buttons, votes, active states |
onClose | () => void | No | Called when user taps the close button |
safeAreaTop | number | No | Top safe area inset (for full-screen modals) |
safeAreaBottom | number | No | Bottom safe area inset (for full-screen modals) |
keyboardVerticalOffset | number | No | Offset for the keyboard in a modal |
theme | Partial<FeaturamaTheme> | No | Override individual theme colors |
FeaturamaView for Swift
| Parameter | Type | Required | Description |
|---|---|---|---|
accentColor | Color | No | Accent color for buttons, votes, active states; defaults to .blue |
colorScheme | ColorScheme? | No | Force light/dark (defaults to system) |
theme | FeaturamaThemeOverrides? | No | Override individual theme colors |
onClose | (() -> Void)? | No | Called when user taps the close button |
strings | FeaturamaStrings | No | Custom localization strings; defaults to English strings |
submitterIdentifier | String? | No | Stable identity for submissions, owner edits and voting; defaults to a persisted installation ID |
Flutter, Android and .NET MAUI
| SDK | Screen | Configuration |
|---|---|---|
| Flutter | FeaturamaScreen | Required client; optional accentColor, brightness, onClose, strings, submitterIdentifier. Brightness defaults to light; pass the host theme to follow the system. |
| Android | FeaturamaScreen composable | Optional accentColor, isDarkTheme, onClose, strings. Uses the configured Featurama singleton; dark mode defaults to the system. |
| .NET MAUI | FeaturamaPage | Accepts FeaturamaPageOptions with AccentColor, ColorScheme, OnClose, OnCloseAsync, Strings, SubmitterIdentifier, DeviceInfo. Color scheme defaults to light. OnCloseAsync takes precedence over OnClose. |
See SDK setup for tested platforms, toolchain requirements and the difference between browser, native control and OS-level UI verification. Flutter's detail, comment, comment-vote and owner-edit flows passed in the browser and in Release on a physical iPhone and an Android emulator, including failed-write draft retention and retry. Native workflows used Flutter integration automation; this is not a claim of hardware-keyboard or every-OS-version coverage. These local source previews are not published releases.
Theming
For React Native and Swift, the theme is generated from colorScheme and accentColor. Override colors with the theme prop. The other SDKs use the screen options listed above; they do not accept this same React Native/Swift override object:
<FeatureRequestsScreen
colorScheme="dark"
accentColor="#4cb211"
theme={{
background: '#1a1a2e',
card: '#16213e',
}}
/>Available theme keys:
| Key | Description |
|---|---|
background | Page background |
card | Card/item background |
secondary | Secondary background |
text | Primary text color |
textSecondary | Secondary/muted text |
accent | Accent color (buttons, links) |
accentLight | Light accent variant |
accentForeground | Text on accent background |
border | Default border color |
borderAccent | Accent border color |
gray100 | Neutral gray |
warning | Warning accent (pending review) |
warningLight | Warning background |
warningText | Warning text |
Localization
React Native and Swift support localization as follows. The source previews also expose FeaturamaStrings through their strings or Strings option; their keys differ, so use the class from the corresponding SDK rather than copying another platform's object.
React Native: Language is auto-detected from the device locale. No configuration needed. Supported: English, German, French, Spanish, Portuguese, Italian, Dutch, Polish, Japanese, Korean, Chinese. Detection order: expo-localization > react-native-localize > NativeModules > English fallback.
Swift: Pass custom strings for full localization:
let strings = FeaturamaStrings(
title: "Funktionswünsche",
filterNew: "Neu",
pendingReview: "Wartet auf Freigabe",
newRequest: "Neuer Wunsch"
)
FeaturamaView(accentColor: .blue, strings: strings)Features included
The list below describes the React Native and Swift screens. SDK-specific additions follow; this is not a blanket cross-platform verification claim.
- Filter tabs. New, In Progress, Done
- Create form. Title, description, optional email (respects project's email collection setting)
- Vote toggle. Tap to vote, tap again to remove vote
- Detail view. Full request details with comment thread
- Comments. View, add, and vote on comments
- Pending badge. Shows "Pending Review" for unapproved submissions
- Branding. "Powered by Featurama" footer (controlled in Dashboard Settings)
- Developer badge. Comments from developers show a "Developer" label
Flutter detail and editing
Open a request from FeaturamaScreen to read its full title, description, status and comments. The built-in discussion supports adding comments, developer badges, comment vote toggles, refresh and retry. The owner can comment on a pending request; comment voting stays disabled until approval.
Edit appears only when the request's submitter identifier matches the current screen identity. The prefilled form edits title and description, validates required fields and retains the draft after a failed save. Failed comment submissions also keep their text. Omit submitterIdentifier to use the persisted installation ID, or supply your own stable identity. Changing the client or identity resets the open request and draft.
MAUI owner editing and metadata
FeaturamaPage shows Edit on the owner's request card. Its prefilled form validates title and description, disables controls while saving and preserves failed-save drafts for retry. Successful edits keep the current list filter and page. The page captures its client and identity when opened, so reconfiguring the global SDK does not move an open draft to another project. Open a new page after switching projects or identities.
Native submissions collect permission-free app, OS and device metadata. Set FeaturamaPageOptions.DeviceInfo to replace the complete automatic object, or pass an empty new Featurama.Maui.Models.DeviceInfo() to disable collection. Portable net10.0 clients supply metadata themselves.
Flutter and MAUI installation identifiers are client-supplied values, not authenticated accounts. Owner-only controls do not replace server validation or make pending requests private. See Approval and review.
Navigation examples
Wrap the route or a parent layout in FeaturamaProvider. These examples only show the screen inside that existing provider.
// app/feedback.tsx
import { FeatureRequestsScreen } from '@vibelabsdotto/featurama-rn-expo';
import { useRouter } from 'expo-router';
import { useColorScheme } from 'react-native';
export default function FeedbackModal() {
const router = useRouter();
const colorScheme = useColorScheme() ?? 'light';
return (
<FeatureRequestsScreen
colorScheme={colorScheme}
accentColor="#6366f1"
onClose={() => router.back()}
/>
);
}