React Components
React components for building Settings views that match the Studio design system
React Components
The SDK provides pre-styled React components for building Settings views that match Studio's design system, including light and dark color schemes. Import from @telemetryos/sdk/react.
info Always use these components for Settings views. Raw HTML elements won't look correct in Studio.
Debounce Guidelines
Store hooks accept an optional debounce delay (default 0ms - immediate). Choose based on input type:
| Input Type | Debounce | Reason |
|---|---|---|
| Text input | 250ms | Wait for typing to pause |
| Textarea | 250ms | Wait for typing to pause |
| Select/Dropdown | 0ms (default) | Immediate feedback expected |
| Switch/Toggle | 0ms (default) | Immediate feedback expected |
| Checkbox | 0ms (default) | Immediate feedback expected |
| Radio | 0ms (default) | Immediate feedback expected |
| Slider | 5ms | Responsive feel, reduced message traffic |
| Color picker | 5ms | Responsive feel while dragging |
Usage:
// Text input - debounce to wait for typing to pause
const [isLoading, city, setCity] = useCityStoreState(250)
// Dropdown - immediate (default, no argument needed)
const [isLoading, league, setLeague] = useLeagueStoreState()
// Slider - responsive (5ms)
const [isLoading, volume, setVolume] = useVolumeStoreState(5)Container & Layout
SettingsContainer
Root wrapper for all Settings content. Handles color scheme synchronization with Studio.
import { SettingsContainer } from '@telemetryos/sdk/react'
function Settings() {
return (
<SettingsContainer>
{/* All settings content goes here */}
</SettingsContainer>
)
}SettingsHeading
Section heading used to divide settings into logical sections. Can be used at the container level or inside a SettingsBox.
import { SettingsHeading, SettingsDivider } from '@telemetryos/sdk/react'
<SettingsHeading>Display Options</SettingsHeading>
{/* Fields for this section */}
<SettingsDivider />
<SettingsHeading>Advanced Settings</SettingsHeading>
{/* Fields for next section */}SettingsBox
Bordered container, typically used for individual items in a repeatable list. Each item in a list gets its own box.
import { SettingsBox, SettingsHeading, SettingsButtonFrame } from '@telemetryos/sdk/react'
<SettingsHeading>Teams</SettingsHeading>
{teams.map((team, index) => (
<SettingsBox key={index}>
<SettingsHeading>Team {index + 1}</SettingsHeading>
{/* Team fields */}
<SettingsButtonFrame>
<button onClick={() => removeTeam(index)}>Remove</button>
</SettingsButtonFrame>
</SettingsBox>
))}
<SettingsButtonFrame>
<button onClick={addTeam}>+ Add Team</button>
</SettingsButtonFrame>SettingsDivider
Horizontal rule separator between sections.
import { SettingsDivider } from '@telemetryos/sdk/react'
<SettingsDivider />Field Structure
SettingsField, SettingsLabel
Wrapper for each form field with its label. SettingsField renders as a <label> element, so clicking the label text will activate the input inside.
import { SettingsField, SettingsLabel } from '@telemetryos/sdk/react'
<SettingsField>
<SettingsLabel>Field Label</SettingsLabel>
{/* Input component goes here */}
</SettingsField>SettingsHint
Optional hint text displayed below a field input.
import { SettingsField, SettingsLabel, SettingsInputFrame, SettingsHint } from '@telemetryos/sdk/react'
<SettingsField>
<SettingsLabel>API Key</SettingsLabel>
<SettingsInputFrame>
<input type="text" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
</SettingsInputFrame>
<SettingsHint>Found in the dashboard under Settings → API</SettingsHint>
</SettingsField>SettingsError
Error message displayed below a field input.
import { SettingsField, SettingsLabel, SettingsInputFrame, SettingsError } from '@telemetryos/sdk/react'
<SettingsField>
<SettingsLabel>Email</SettingsLabel>
<SettingsInputFrame>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
</SettingsInputFrame>
{error && <SettingsError>{error}</SettingsError>}
</SettingsField>Text Inputs
SettingsInputFrame
Styled wrapper for text inputs.
import {
SettingsContainer,
SettingsField,
SettingsLabel,
SettingsInputFrame,
} from '@telemetryos/sdk/react'
import { useTeamStoreState } from '../hooks/store'
function Settings() {
const [isLoading, team, setTeam] = useTeamStoreState(250) // 250ms debounce for text input
return (
<SettingsContainer>
<SettingsField>
<SettingsLabel>Team Name</SettingsLabel>
<SettingsInputFrame>
<input
type="text"
placeholder="Enter team name..."
disabled={isLoading}
value={team}
onChange={(e) => setTeam(e.target.value)}
/>
</SettingsInputFrame>
</SettingsField>
</SettingsContainer>
)
}SettingsTextAreaFrame
Styled wrapper for multiline text inputs.
import { SettingsTextAreaFrame } from '@telemetryos/sdk/react'
import { useDescriptionStoreState } from '../hooks/store'
const [isLoading, description, setDescription] = useDescriptionStoreState(250) // 250ms debounce for textarea
<SettingsField>
<SettingsLabel>Description</SettingsLabel>
<SettingsTextAreaFrame>
<textarea
placeholder="Enter description..."
disabled={isLoading}
value={description}
onChange={(e) => setDescription(e.target.value)}
rows={4}
/>
</SettingsTextAreaFrame>
</SettingsField>Selection Inputs
SettingsSelectFrame
Styled wrapper for dropdown selects.
import { SettingsSelectFrame } from '@telemetryos/sdk/react'
import { useLeagueStoreState } from '../hooks/store'
const [isLoading, league, setLeague] = useLeagueStoreState(0) // 0ms for immediate feedback
<SettingsField>
<SettingsLabel>League</SettingsLabel>
<SettingsSelectFrame>
<select
disabled={isLoading}
value={league}
onChange={(e) => setLeague(e.target.value)}
>
<option value="nfl">NFL</option>
<option value="nba">NBA</option>
<option value="mlb">MLB</option>
<option value="nhl">NHL</option>
</select>
</SettingsSelectFrame>
</SettingsField>SettingsSliderFrame
Styled wrapper for range sliders.
import { SettingsSliderFrame } from '@telemetryos/sdk/react'
import { useVolumeStoreState } from '../hooks/store'
const [isLoading, volume, setVolume] = useVolumeStoreState(5) // 5ms for responsive feel
<SettingsField>
<SettingsLabel>Volume</SettingsLabel>
<SettingsSliderFrame>
<input
type="range"
min="0"
max="100"
disabled={isLoading}
value={volume}
onChange={(e) => setVolume(Number(e.target.value))}
/>
<span>{volume}%</span> {/* Optional value label */}
</SettingsSliderFrame>
</SettingsField>The frame uses flexbox layout, so you can optionally add a <span> after the input to display the current value.
SettingsSliderRuler
Optional ruler with tick labels displayed below a slider.
import { SettingsSliderFrame, SettingsSliderRuler } from '@telemetryos/sdk/react'
<SettingsField>
<SettingsLabel>Quality</SettingsLabel>
<SettingsSliderFrame>
<input
type="range"
min="1"
max="3"
value={quality}
onChange={(e) => setQuality(Number(e.target.value))}
/>
<span>{quality}</span>
</SettingsSliderFrame>
<SettingsSliderRuler>
<span>Low</span>
<span>Medium</span>
<span>High</span>
</SettingsSliderRuler>
</SettingsField>SettingsColorFrame
Styled wrapper for color picker inputs. Displays the color swatch alongside the hex value.
import { SettingsColorFrame } from '@telemetryos/sdk/react'
import { useColorStoreState } from '../hooks/store'
const [isLoading, color, setColor] = useColorStoreState(5) // 5ms for responsive feel while dragging
<SettingsField>
<SettingsLabel>Brand Color</SettingsLabel>
<SettingsColorFrame>
<input
type="color"
disabled={isLoading}
value={color}
onChange={(e) => setColor(e.target.value)}
/>
<span>{color}</span>
</SettingsColorFrame>
</SettingsField>Toggle Inputs
SettingsSwitchFrame, SettingsSwitchLabel
Styled wrapper for toggle switches.
import { SettingsSwitchFrame, SettingsSwitchLabel } from '@telemetryos/sdk/react'
import { useShowScoresStoreState } from '../hooks/store'
const [isLoading, showScores, setShowScores] = useShowScoresStoreState(0) // 0ms for immediate feedback
<SettingsField>
<SettingsSwitchFrame>
<input
type="checkbox"
role="switch"
disabled={isLoading}
checked={showScores}
onChange={(e) => setShowScores(e.target.checked)}
/>
<SettingsSwitchLabel>Show Live Scores</SettingsSwitchLabel>
</SettingsSwitchFrame>
</SettingsField>SettingsCheckboxFrame, SettingsCheckboxLabel
Styled wrapper for checkboxes.
import { SettingsCheckboxFrame, SettingsCheckboxLabel } from '@telemetryos/sdk/react'
import { useAutoRefreshStoreState } from '../hooks/store'
const [isLoading, autoRefresh, setAutoRefresh] = useAutoRefreshStoreState(0) // 0ms for immediate feedback
<SettingsField>
<SettingsCheckboxFrame>
<input
type="checkbox"
disabled={isLoading}
checked={autoRefresh}
onChange={(e) => setAutoRefresh(e.target.checked)}
/>
<SettingsCheckboxLabel>Enable Auto-Refresh</SettingsCheckboxLabel>
</SettingsCheckboxFrame>
</SettingsField>SettingsRadioFrame, SettingsRadioLabel
Styled wrapper for radio button groups.
import { SettingsRadioFrame, SettingsRadioLabel } from '@telemetryos/sdk/react'
import { useDisplayModeStoreState } from '../hooks/store'
const [isLoading, displayMode, setDisplayMode] = useDisplayModeStoreState(0) // 0ms for immediate feedback
<SettingsField>
<SettingsLabel>Display Mode</SettingsLabel>
<SettingsRadioFrame>
<input
type="radio"
name="displayMode"
value="compact"
disabled={isLoading}
checked={displayMode === 'compact'}
onChange={(e) => setDisplayMode(e.target.value)}
/>
<SettingsRadioLabel>Compact</SettingsRadioLabel>
</SettingsRadioFrame>
<SettingsRadioFrame>
<input
type="radio"
name="displayMode"
value="expanded"
disabled={isLoading}
checked={displayMode === 'expanded'}
onChange={(e) => setDisplayMode(e.target.value)}
/>
<SettingsRadioLabel>Expanded</SettingsRadioLabel>
</SettingsRadioFrame>
</SettingsField>Actions
SettingsButtonFrame
Styled wrapper for action buttons.
import { SettingsButtonFrame } from '@telemetryos/sdk/react'
<SettingsButtonFrame>
<button onClick={handleReset}>Reset to Defaults</button>
</SettingsButtonFrame>Component Reference
| Component | Purpose |
|---|---|
SettingsContainer | Root wrapper, handles color scheme |
SettingsHeading | Section heading |
SettingsBox | Container for list items |
SettingsDivider | Horizontal separator |
SettingsField | Wrapper for each field (renders as label) |
SettingsLabel | Field label |
SettingsHint | Help text below a field |
SettingsError | Error message below a field |
SettingsInputFrame | Text input wrapper |
SettingsTextAreaFrame | Multiline text wrapper |
SettingsSelectFrame | Dropdown wrapper |
SettingsSliderFrame | Range slider wrapper |
SettingsSliderRuler | Tick labels below a slider |
SettingsColorFrame | Color picker wrapper |
SettingsSwitchFrame | Toggle switch wrapper |
SettingsSwitchLabel | Toggle switch label |
SettingsCheckboxFrame | Checkbox wrapper |
SettingsCheckboxLabel | Checkbox label |
SettingsRadioFrame | Radio button wrapper |
SettingsRadioLabel | Radio button label |
SettingsButtonFrame | Action button wrapper |
Updated about 1 hour ago