Theming
React Native has no CSS, so the kit keeps its colors in a ListensTheme object. It's the same palette as the web kits' --listens-* tokens, with camelCase keys: --listens-text-secondary is textSecondary. Every control reads it, the provider takes your overrides, and useListensTheme() hands it to your own components.
Change a color
Pass the keys you want to change to the provider's theme prop. They're merged over the defaults for the device's light or dark setting, so every key you leave out keeps its usual value.
App.tsx
import { ListensProvider } from '@listenssoft/speechui-react-native';
const theme = {
// Labels and content while the mic is open.
accent: '#7c3aed',
// Focus, highlighted options, and checkbox, radio and slider fills.
interactive: '#7c3aed',
};
export default function App() {
return (
<ListensProvider licenseKey="YOUR_LICENSE_KEY" theme={theme}>
{/* …the rest of your app */}
</ListensProvider>
);
}
These values apply in light and dark mode alike. To give dark mode its own values, see different colors in light and dark.
Light and dark mode
The controls, the listening bar and the popup follow the device's light or dark setting automatically. To switch them yourself, pass LISTENS_DARK_THEME or LISTENS_LIGHT_THEME as the provider's theme, and leave theme out to follow the device again.
The React Native setup has a dark mode switch built from a ListensToggle, so people can tap it or say "dark mode".
Different colors in light and dark
Spread your keys over a full theme for each mode, then pick one. Here the device decides; for an in-app switch, use your own state instead of scheme.
App.tsx
import {
LISTENS_DARK_THEME,
LISTENS_LIGHT_THEME,
ListensProvider,
} from '@listenssoft/speechui-react-native';
import { useColorScheme } from 'react-native';
const light = { ...LISTENS_LIGHT_THEME, accent: '#7c3aed' };
const dark = { ...LISTENS_DARK_THEME, accent: '#a78bfa' };
export default function App() {
const scheme = useColorScheme();
return (
<ListensProvider
licenseKey="YOUR_LICENSE_KEY"
theme={scheme === 'dark' ? dark : light}
>
{/* …the rest of your app */}
</ListensProvider>
);
}
Match your own components
Native text is black unless you give it a color, so text you render next to the controls can disappear in dark mode. useListensTheme() returns the active theme, with the provider's overrides already merged in, so your own views can use the same colors as the controls in either mode:
OrderTotal.tsx
import { useListensTheme } from '@listenssoft/speechui-react-native';
import { Text, View } from 'react-native';
export function OrderTotal({ total }: { total: string }) {
const theme = useListensTheme();
return (
<View
style={{
backgroundColor: theme.surface,
borderColor: theme.border,
borderWidth: 1,
borderRadius: 8,
padding: 12,
}}
>
<Text style={{ color: theme.label }}>Total</Text>
<Text style={{ color: theme.text, fontSize: 18 }}>{total}</Text>
</View>
);
}
Outside a provider, it returns the defaults for the device's setting.
Style one control
The theme restyles every control at once. React Native has no classes, so there's no className: to change just one control, pass it a style. Some controls also take narrower props, such as the label button's textStyle. Each control's page lists its style props and the theme keys it reads under Styling hooks, for example the label button's.
The listening bar and popup
The bar and the popup take their colors from the theme's barBackground and barText, so forcing a theme flips them too. To change one surface only, use its props: waveColor on both, and backgroundColor and textColor on the popup. See the listening bar and popup page.
Theme reference
Every key in ListensTheme, with its light and dark default. The first four groups match the web kits' tokens.
| Key | Light | Dark |
|---|---|---|
| Listening signal | ||
accentLabels and content while the mic is open. The one color every control shares. | #ff0000 | #ff0000 |
| Text | ||
textPrimary control text. | #222222 | #ededed |
textSecondaryValues and secondary readouts. | #444444 | #c2c2c2 |
labelField labels. | #666666 | #a6a6a6 |
textMutedIdle toggle button text and “no results” messages. | #888888 | #8f8f8f |
textSubtleIcons, empty states, delete buttons and disabled text. | #999999 | #7d7d7d |
textStrongThe strongest emphasis, such as the selected ring. | #000000 | #ffffff |
onAccentText and icons on an accent fill. | #ffffff | #ffffff |
placeholderInput placeholders. | #9a9a9a | #7d7d7d |
| Surfaces and borders | ||
surfaceInputs, menus, list items and cards. | #ffffff | #2a2a2a |
borderDefault borders and input outlines. | #d0d0d0 | #4a4a4a |
borderSubtleFaint dividers. | #e0e0e0 | #3a3a3a |
buttonBorderThe soft edge around buttons. | rgba(0, 0, 0, 0.12) | rgba(255, 255, 255, 0.13) |
buttonFaceButton fill. | #efefef | #6b6b6b |
onButtonText on a button fill. | #222222 | #ffffff |
menuHairlineThe edge of the combobox menu. | rgba(0, 0, 0, 0.05) | rgba(255, 255, 255, 0.12) |
ringThe selection ring’s shadow. | rgba(0, 0, 0, 0.2) | rgba(255, 255, 255, 0.28) |
| Interactive | ||
interactiveFocus, highlighted options, and checkbox, radio and slider fills. | #007aff | #0a84ff |
successThe toggle’s track when on. | #4caf50 | #46c463 |
trackThe toggle’s track when off. | #dddddd | #555555 |
toggleThumbThe toggle’s thumb. | #ffffff | #f0f0f0 |
segmentOnA checked toggle button’s fill. | #64b5f6 | #0a84ff |
segmentOnBorderA checked standalone toggle button’s border. | #2196f3 | #409cff |
dangerDestructive hovers, such as delete. | #e53935 | #ff6b6b |
| Listening bar and popup | ||
barBackgroundThe bar’s background, and the popup’s (which applies its design’s transparency). | rgb(245, 245, 245) | rgb(28, 28, 30) |
barTextThe transcript in the bar and the popup. | #222222 | #ededed |