One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

Android Compose

Jetpack Compose views under One.Android

One.Android Compose card with a switch, slider, chips, buttons, and a progress indicator

Jetpack Compose views under One.Android, drawn by Material 3.

Usage

import { useState } from 'react'
import { One } from 'one'
export function Settings() {
const [on, setOn] = useState(true)
return (
<One.Android.Card composeStyle={{ padding: 16 }}>
<One.Android.Switch label="Airplane mode" isOn={on} onIsOnChange={setOn} />
</One.Android.Card>
)
}

Shared props

Every node takes these. A node inside a Compose tree styles through composeStyle; style applies only at the root of the tree.

PropsTypeDescription
childrenReactNodeCompose children, on layout nodes.
ReactNodeCompose children, on layout nodes.
accessibilityRoleComposeAccessibilityRolebutton, switch, checkbox, radio, header, text, adjustable, alert, or progressbar.
ComposeAccessibilityRolebutton, switch, checkbox, radio, header, text, adjustable, alert, or progressbar.
styleStyleProp<ViewStyle>React Native style, at the root of a Compose tree only.
StyleProp<ViewStyle>React Native style, at the root of a Compose tree only.
composeStyleComposeStyleCompose modifiers. See below.
ComposeStyleCompose modifiers. See below.

Nodes also take accessibilityLabel, accessibilityState, accessibilityValue, and testID.

ComposeStyleTypeDescription
backgroundColorColorValueThe fill behind the node.
ColorValueThe fill behind the node.
foregroundColorColorValueThe content color, such as an icon tint.
ColorValueThe content color, such as an icon tint.
paddingnumberPadding on every side, in dp.
numberPadding on every side, in dp.
paddingTopnumberTop padding, in dp.
numberTop padding, in dp.
paddingRightnumberRight padding, in dp.
numberRight padding, in dp.
paddingBottomnumberBottom padding, in dp.
numberBottom padding, in dp.
paddingLeftnumberLeft padding, in dp.
numberLeft padding, in dp.
widthnumberA fixed width, in dp.
numberA fixed width, in dp.
heightnumberA fixed height, in dp.
numberA fixed height, in dp.
fillMaxWidthbooleanFills the parent width.
booleanFills the parent width.
fillMaxHeightbooleanFills the parent height.
booleanFills the parent height.
weightnumberA share of the free space in a Row or Column.
numberA share of the free space in a Row or Column.
cornerRadiusnumberRounds the node, in dp.
numberRounds the node, in dp.
opacitynumberFrom 0 to 1.
numberFrom 0 to 1.
borderColorColorValueThe border color.
ColorValueThe border color.
borderWidthnumberThe border width, in dp.
numberThe border width, in dp.

Column, Row, Box

One.Android.Column stacks children vertically, Row horizontally, and Box layers them.

ColumnTypeDescription
horizontalAlignmentComposeHorizontalAlignment = "start"start, centerHorizontally, or end.
ComposeHorizontalAlignment = "start"start, centerHorizontally, or end.
verticalArrangementComposeVerticalArrangement = "top"top, center, bottom, spaceBetween, spaceAround, or spaceEvenly.
ComposeVerticalArrangement = "top"top, center, bottom, spaceBetween, spaceAround, or spaceEvenly.
spacingnumberThe gap between children, in dp.
numberThe gap between children, in dp.
RowTypeDescription
verticalAlignmentComposeVerticalAlignment = "top"top, centerVertically, or bottom.
ComposeVerticalAlignment = "top"top, centerVertically, or bottom.
horizontalArrangementComposeHorizontalArrangement = "start"start, center, end, spaceBetween, spaceAround, or spaceEvenly.
ComposeHorizontalArrangement = "start"start, center, end, spaceBetween, spaceAround, or spaceEvenly.
spacingnumberThe gap between children, in dp.
numberThe gap between children, in dp.
BoxTypeDescription
contentAlignmentComposeContentAlignmentWhere children sit: topStart through bottomEnd, or top, bottom, start, end.
ComposeContentAlignmentWhere children sit: topStart through bottomEnd, or top, bottom, start, end.

One.Android.FlowRow wraps children across rows.

FlowRowTypeDescription
horizontalArrangementComposeHorizontalArrangement | Readonly<{ spacedBy: number }> = "start"A Row arrangement, or a fixed gap in dp.
ComposeHorizontalArrangement | Readonly<{ spacedBy: number }> = "start"A Row arrangement, or a fixed gap in dp.
verticalArrangementComposeVerticalArrangement | Readonly<{ spacedBy: number }> = "top"A Column arrangement, or a fixed gap between rows in dp.
ComposeVerticalArrangement | Readonly<{ spacedBy: number }> = "top"A Column arrangement, or a fixed gap between rows in dp.

One.Android.Spacer takes the shared props only. As a direct child of a Row or Column with composeStyle={{ weight: 1 }} it takes the free space; with width or height it is a fixed gap. Any other direct child takes a positive weight the same way.

Text

PropsTypeDescription
text (required)stringThe text.
stringThe text.
fontSizenumberThe size in sp. The theme body size when unset.
numberThe size in sp. The theme body size when unset.
fontWeightComposeFontWeightthin, extraLight, light, normal, medium, semiBold, bold, extraBold, or black.
ComposeFontWeightthin, extraLight, light, normal, medium, semiBold, bold, extraBold, or black.
textAlignComposeTextAlignunspecified, left, right, center, justify, start, or end.
ComposeTextAlignunspecified, left, right, center, justify, start, or end.
maxLinesnumberThe most lines shown.
numberThe most lines shown.

Icon

One.Android.Icon draws a Material Symbol. See Android Icons. For an icon on every platform, use One.UI.Icon.

Buttons

One.Android.Button shows a label with an optional leading icon.

ButtonTypeDescription
label (required)stringThe title.
stringThe title.
onPress() => voidRuns when tapped.
() => voidRuns when tapped.
variantComposeButtonVariant = "filled"filled, tonal, elevated, outlined, or text.
ComposeButtonVariant = "filled"filled, tonal, elevated, outlined, or text.
toneComposeButtonTone = "default"default, or danger for the error colors.
ComposeButtonTone = "default"default, or danger for the error colors.
iconComposeIconNameA Material Symbol before the label.
ComposeIconNameA Material Symbol before the label.
iconFilledboolean = falseUses the filled icon font.
boolean = falseUses the filled icon font.
disabledboolean = falseDims the button and ignores taps.
boolean = falseDims the button and ignores taps.

IconButton, FilledIconButton, FilledTonalIconButton, and OutlinedIconButton wrap an Icon child.

IconButtonTypeDescription
children (required)ReactNodeThe Icon.
ReactNodeThe Icon.
onClick() => voidRuns when tapped.
() => voidRuns when tapped.
enabledbooleanfalse dims the button and ignores taps.
booleanfalse dims the button and ignores taps.
colorsComposeIconButtonColorsContainer and content colors, enabled and disabled.
ComposeIconButtonColorsContainer and content colors, enabled and disabled.

FloatingActionButton, SmallFloatingActionButton, and LargeFloatingActionButton take an Icon in their .Icon slot. ExtendedFloatingActionButton also takes Text in .Text.

FloatingActionButtonTypeDescription
children (required)ReactNodeThe .Icon and, when extended, .Text slots.
ReactNodeThe .Icon and, when extended, .Text slots.
containerColorColorValueThe button color. The theme when unset.
ColorValueThe button color. The theme when unset.
onClick() => voidRuns when tapped.
() => voidRuns when tapped.

ExtendedFloatingActionButton adds expanded, which shows or hides its text.

ToggleButton, IconToggleButton, FilledIconToggleButton, and OutlinedIconToggleButton are the Material 3 toggles.

ToggleButtonTypeDescription
children (required)ReactNodeThe content, such as an Icon.
ReactNodeThe content, such as an Icon.
checked (required)booleanWhether the toggle is on.
booleanWhether the toggle is on.
onCheckedChange(checked: boolean) => voidA tap, with the new value.
(checked: boolean) => voidA tap, with the new value.
enabledboolean = truefalse dims the toggle and ignores taps.
boolean = truefalse dims the toggle and ignores taps.
colorsComposeToggleButtonColorsContainer and content colors, normal, checked, and disabled.
ComposeToggleButtonColorsContainer and content colors, normal, checked, and disabled.
revisionnumber = 0Increase with a new checked to reset it from outside.
number = 0Increase with a new checked to reset it from outside.

Segmented buttons

SingleChoiceSegmentedButtonRow and MultiChoiceSegmentedButtonRow hold SegmentedButton children. In a single choice row, pass selected and onClick; in a multiple choice row, pass checked and onCheckedChange.

SegmentedButtonTypeDescription
children (required)ReactNodeThe segment label.
ReactNodeThe segment label.
selectedbooleanWhether the segment is chosen, in a single choice row.
booleanWhether the segment is chosen, in a single choice row.
onClick() => voidA tap, in a single choice row.
() => voidA tap, in a single choice row.
checkedbooleanWhether the segment is on, in a multiple choice row.
booleanWhether the segment is on, in a multiple choice row.
onCheckedChange(checked: boolean) => voidA tap, in a multiple choice row.
(checked: boolean) => voidA tap, in a multiple choice row.
enabledboolean = truefalse dims the segment and ignores taps.
boolean = truefalse dims the segment and ignores taps.
colorsComposeSegmentedButtonColorsBorder, content, and container colors, active, inactive, and disabled.
ComposeSegmentedButtonColorsBorder, content, and container colors, active, inactive, and disabled.
revisionnumber = 0Increase with a new checked to reset it from outside.
number = 0Increase with a new checked to reset it from outside.

Switch

PropsTypeDescription
isOn (required)booleanWhether the switch is on.
booleanWhether the switch is on.
onIsOnChange (required)(value: boolean) => voidA flip, with the new value.
(value: boolean) => voidA flip, with the new value.
labelstring = ""Text before the switch. The whole row toggles.
string = ""Text before the switch. The whole row toggles.
disabledboolean = falseDims the switch and ignores taps.
boolean = falseDims the switch and ignores taps.
colorsComposeSwitchColorsThumb, track, border, and icon colors for each state.
ComposeSwitchColorsThumb, track, border, and icon colors for each state.
revisionnumber = 0Increase with a new isOn to reset it from outside.
number = 0Increase with a new isOn to reset it from outside.

Checkbox, RadioButton

Without a callback, each is read only. Omitted colors use the Material theme.

CheckboxTypeDescription
value (required)booleanWhether the box is checked.
booleanWhether the box is checked.
onCheckedChange(value: boolean) => voidA tap, with the new value.
(value: boolean) => voidA tap, with the new value.
disabledboolean = falseDims the box and ignores taps.
boolean = falseDims the box and ignores taps.
revisionnumber = 0Increase with a new value to reset it from outside.
number = 0Increase with a new value to reset it from outside.
colorsReadonly<{ checkedColor?: ColorValue disabledCheckedColor?: ColorValue uncheckedColor?: ColorValue disabledUncheckedColor?: ColorValue checkmarkColor?: ColorValue }>Box and checkmark colors.
Readonly<{ checkedColor?: ColorValue disabledCheckedColor?: ColorValue uncheckedColor?: ColorValue disabledUncheckedColor?: ColorValue checkmarkColor?: ColorValue }>Box and checkmark colors.
RadioButtonTypeDescription
selected (required)booleanWhether the button is chosen.
booleanWhether the button is chosen.
onClick() => voidA tap. Set selected yourself.
() => voidA tap. Set selected yourself.
disabledboolean = falseDims the button and ignores taps.
boolean = falseDims the button and ignores taps.
colorsReadonly<{ selectedColor?: ColorValue unselectedColor?: ColorValue disabledSelectedColor?: ColorValue disabledUnselectedColor?: ColorValue }>Ring and dot colors.
Readonly<{ selectedColor?: ColorValue unselectedColor?: ColorValue disabledSelectedColor?: ColorValue disabledUnselectedColor?: ColorValue }>Ring and dot colors.

Cards, Surface

Card, ElevatedCard, and OutlinedCard wrap children in the Material 3 card surfaces. ElevatedCard takes no border. Without one, Card has no border and OutlinedCard uses the theme outline.

CardTypeDescription
colorsComposeCardColors{ containerColor, contentColor }.
ComposeCardColors{ containerColor, contentColor }.
elevationnumberThe shadow depth in dp. Zero or more.
numberThe shadow depth in dp. Zero or more.
borderComposeCardBorder{ width, color }, width in dp, 1 by default.
ComposeCardBorder{ width, color }, width in dp, 1 by default.

One.Android.Surface is a Material 3 surface. Round it with composeStyle.cornerRadius. With onClick it is clickable, with selected and onClick selectable, and with checked and onCheckedChange toggleable.

SurfaceTypeDescription
colorColorValueThe surface color.
ColorValueThe surface color.
contentColorColorValueThe color of content on it.
ColorValueThe color of content on it.
tonalElevationnumberTints the surface by depth, in dp.
numberTints the surface by depth, in dp.
shadowElevationnumberThe shadow depth, in dp.
numberThe shadow depth, in dp.
borderComposeCardBorder{ width, color }.
ComposeCardBorder{ width, color }.
enabledboolean = truefalse ignores taps.
boolean = truefalse ignores taps.
selectedbooleanMakes it selectable, with onClick.
booleanMakes it selectable, with onClick.
checkedbooleanMakes it toggleable, with onCheckedChange.
booleanMakes it toggleable, with onCheckedChange.
onClick() => voidRuns when tapped.
() => voidRuns when tapped.
onCheckedChange(checked: boolean) => voidA tap, with the new checked value.
(checked: boolean) => voidA tap, with the new checked value.
revisionnumber = 0Increase with a new checked to reset it from outside.
number = 0Increase with a new checked to reset it from outside.

ListItem

One.Android.ListItem is a Material 3 row. Put Compose content in its .HeadlineContent slot, and optionally .OverlineContent, .SupportingContent, .LeadingContent, and .TrailingContent.

PropsTypeDescription
colorsComposeListItemColorsContainer and per slot content colors.
ComposeListItemColorsContainer and per slot content colors.
tonalElevationnumberTints the row by depth, in dp.
numberTints the row by depth, in dp.
shadowElevationnumberThe shadow depth, in dp.
numberThe shadow depth, in dp.

Dividers

HorizontalDivider and VerticalDivider draw Material 3 lines. Give a vertical divider a height through its parent or composeStyle.

PropsTypeDescription
thicknessnumberThe line width in dp.
numberThe line width in dp.
colorColorValueThe line color. The theme when unset.
ColorValueThe line color. The theme when unset.

Badges

One.Android.Badge is a dot, or a count when it has Compose children. One.Android.BadgedBox puts a Badge from its .Badge slot at the top end of its content; with no slot it shows a dot.

BadgeTypeDescription
containerColorColorValueThe badge color.
ColorValueThe badge color.
contentColorColorValueThe count color.
ColorValueThe count color.

Chips

AssistChip, FilterChip, InputChip, and SuggestionChip are the Material 3 chips. Each takes its label in a .Label slot. AssistChip and FilterChip also have .LeadingIcon and .TrailingIcon, InputChip has .Avatar and .TrailingIcon, and SuggestionChip has .Icon.

Every chip takes enabled, onClick, elevation in dp, border ({ width, color }), and colors. A tap calls onClick; set the next selected yourself.

FilterChipTypeDescription
selected (required)booleanWhether the filter is on.
booleanWhether the filter is on.
colorsComposeFilterChipColorsContainer, label, and icon colors, normal and selected.
ComposeFilterChipColorsContainer, label, and icon colors, normal and selected.
InputChipTypeDescription
selectedboolean = falseWhether the chip is selected.
boolean = falseWhether the chip is selected.
colorsComposeInputChipColorsContainer, label, and icon colors, normal and selected.
ComposeInputChipColorsContainer, label, and icon colors, normal and selected.

AssistChip colors are containerColor, labelColor, leadingIconContentColor, and trailingIconContentColor. SuggestionChip colors are containerColor, labelColor, and iconContentColor.

TextField

One.Android.TextField edits text, a string or a native state handle from useNativeState. For a field on every platform, use One.UI.TextInput.

PropsTypeDescription
text (required)string | NativeState<string>The text, or a native state handle.
string | NativeState<string>The text, or a native state handle.
onTextChange (required)(value: string) => voidAn edit, with the new text.
(value: string) => voidAn edit, with the new text.
revisionnumber = 0Increase with a new text to reset it from outside.
number = 0Increase with a new text to reset it from outside.
labelstringThe floating label.
stringThe floating label.
placeholderstringShown while empty.
stringShown while empty.
disabledboolean = falseDims the field and blocks editing.
boolean = falseDims the field and blocks editing.
variantComposeTextFieldVariant = "filled"filled or outlined.
ComposeTextFieldVariant = "filled"filled or outlined.
keyboardTypeComposeTextFieldKeyboardType = "default"default, number, decimal, email, password, phone, or url.
ComposeTextFieldKeyboardType = "default"default, number, decimal, email, password, phone, or url.
secureTextboolean = falseHides the text.
boolean = falseHides the text.
focusedbooleanWhether the field has focus, controlled.
booleanWhether the field has focus, controlled.
focusRevisionnumber = 0Increase with a new focused to apply it.
number = 0Increase with a new focused to apply it.
onFocusChange(focused: boolean) => voidFocus moved.
(focused: boolean) => voidFocus moved.
imeActionComposeTextFieldImeActionThe keyboard action: default, none, go, search, send, previous, next, or done.
ComposeTextFieldImeActionThe keyboard action: default, none, go, search, send, previous, next, or done.
onSubmit() => voidThe keyboard action key was pressed.
() => voidThe keyboard action key was pressed.
maxLengthnumberThe most characters allowed.
numberThe most characters allowed.
multilineboolean = falseAllows line breaks.
boolean = falseAllows line breaks.
capitalizationComposeTextFieldCapitalizationnone, characters, words, or sentences.
ComposeTextFieldCapitalizationnone, characters, words, or sentences.
autoCorrectbooleanWhether the keyboard corrects words.
booleanWhether the keyboard corrects words.
textAlignComposeTextAlignHow the text aligns.
ComposeTextAlignHow the text aligns.

Slider

PropsTypeDescription
value (required)numberThe current value.
numberThe current value.
onValueChange (required)(value: number) => voidA drag, with the new value.
(value: number) => voidA drag, with the new value.
revisionnumber = 0Increase with a new value to reset it from outside.
number = 0Increase with a new value to reset it from outside.
minimumValuenumber = 0The low end of the track.
number = 0The low end of the track.
maximumValuenumber = 1The high end of the track.
number = 1The high end of the track.
lowerLimitnumberThe lowest the thumb may go. The track still spans the full range.
numberThe lowest the thumb may go. The track still spans the full range.
upperLimitnumberThe highest the thumb may go.
numberThe highest the thumb may go.
stepnumber = 0The increment. 0 is continuous.
number = 0The increment. 0 is continuous.
disabledboolean = falseDims the slider and ignores drags.
boolean = falseDims the slider and ignores drags.
colorsReadonly<{ thumbColor?: ColorValue activeTrackColor?: ColorValue inactiveTrackColor?: ColorValue activeTickColor?: ColorValue inactiveTickColor?: ColorValue }>Thumb, track, and tick colors.
Readonly<{ thumbColor?: ColorValue activeTrackColor?: ColorValue inactiveTrackColor?: ColorValue activeTickColor?: ColorValue inactiveTickColor?: ColorValue }>Thumb, track, and tick colors.

DatePicker, TimePicker

One.Android.DatePicker is the Material 3 calendar and One.Android.TimePicker is the clock dial. Both are controlled by a Date. DatePicker changes the calendar day in the device time zone and keeps the time of day. TimePicker changes the hour and minute, keeps the day, and sets seconds to zero.

const [when, setWhen] = useState(() => new Date())
<One.Android.DatePicker
selection={when}
onSelectionChange={setWhen}
minimumDate={new Date(2026, 0, 1)}
/>
<One.Android.TimePicker selection={when} onSelectionChange={setWhen} is24Hour />
DatePickerTypeDescription
selection (required)DateThe selected day.
DateThe selected day.
onSelectionChange (required)(value: Date) => voidA tapped or typed day, with the time of day kept.
(value: Date) => voidA tapped or typed day, with the time of day kept.
revisionnumber = 0Increase with a new value to reset it from outside.
number = 0Increase with a new value to reset it from outside.
minimumDateDateThe earliest selectable day. Earlier days and years are disabled.
DateThe earliest selectable day. Earlier days and years are disabled.
maximumDateDateThe latest selectable day.
DateThe latest selectable day.
variant'picker' | 'input' = 'picker'The calendar grid or a text field.
'picker' | 'input' = 'picker'The calendar grid or a text field.
showModeToggleboolean = trueShows the button that switches variant.
boolean = trueShows the button that switches variant.
colorColorValueTints the title, headline, selected day, and today border.
ColorValueTints the title, headline, selected day, and today border.
colorsComposeDatePickerColorsPer-element colors; these win over color.
ComposeDatePickerColorsPer-element colors; these win over color.
TimePickerTypeDescription
selection (required)DateThe selected time of day.
DateThe selected time of day.
onSelectionChange (required)(value: Date) => voidA new hour or minute, with the day kept.
(value: Date) => voidA new hour or minute, with the day kept.
revisionnumber = 0Increase with a new value to reset it from outside.
number = 0Increase with a new value to reset it from outside.
is24HourbooleanA 24 hour clock. Defaults to the device setting.
booleanA 24 hour clock. Defaults to the device setting.
variant'picker' | 'input' = 'picker'The clock dial or hour and minute fields.
'picker' | 'input' = 'picker'The clock dial or hour and minute fields.
colorColorValueTints the selector, selected field, and dial.
ColorValueTints the selector, selected field, and dial.
colorsComposeTimePickerColorsPer-element colors; these win over color.
ComposeTimePickerColorsPer-element colors; these win over color.

DatePickerDialog and TimePickerDialog take the same props without onSelectionChange and revision. Each opening starts from selection; the confirm button reports the chosen value.

DatePickerDialog, TimePickerDialogTypeDescription
visible (required)booleanWhether the dialog shows.
booleanWhether the dialog shows.
onConfirm (required)(value: Date) => voidThe confirm button, with the chosen value.
(value: Date) => voidThe confirm button, with the chosen value.
onDismiss (required)() => voidDismissed by the button, a tap outside, or back.
() => voidDismissed by the button, a tap outside, or back.
confirmLabelstringThe confirm button title. Defaults to the system OK.
stringThe confirm button title. Defaults to the system OK.
dismissLabelstringThe dismiss button title. Defaults to the system Cancel.
stringThe dismiss button title. Defaults to the system Cancel.

AlertDialog, Dialog

One.Android.AlertDialog shows a confirmation while visible is true. One.Android.Dialog shows its children in a dialog window.

AlertDialogTypeDescription
visible (required)booleanWhether the dialog shows.
booleanWhether the dialog shows.
titlestringThe headline.
stringThe headline.
messagestringThe body text.
stringThe body text.
confirmLabel (required)stringThe confirm button title.
stringThe confirm button title.
dismissLabelstringThe dismiss button title. No button when unset.
stringThe dismiss button title. No button when unset.
onConfirm (required)() => voidThe confirm button was tapped.
() => voidThe confirm button was tapped.
onDismiss (required)() => voidDismissed by the button, a tap outside, or back.
() => voidDismissed by the button, a tap outside, or back.
DialogTypeDescription
visible (required)booleanWhether the dialog shows.
booleanWhether the dialog shows.
onDismiss (required)() => voidA tap outside or back asked to close it.
() => voidA tap outside or back asked to close it.

Progress and loading

ProgressIndicator is circular unless variant says otherwise. LinearProgressIndicator, CircularProgressIndicator, LinearWavyProgressIndicator, and CircularWavyProgressIndicator fix the variant. Leave progress unset for an indeterminate indicator.

ProgressIndicatorTypeDescription
variantComposeProgressVariant = "circular"linear, circular, linearWavy, or circularWavy.
ComposeProgressVariant = "circular"linear, circular, linearWavy, or circularWavy.
progressnumber | nullFrom 0 to 1. Unset spins.
number | nullFrom 0 to 1. Unset spins.
colorColorValueThe indicator color.
ColorValueThe indicator color.
trackColorColorValueThe track color.
ColorValueThe track color.
strokeCapComposeProgressStrokeCapround, butt, or square. Linear and circular.
ComposeProgressStrokeCapround, butt, or square. Linear and circular.
gapSizenumberThe gap between indicator and track, in dp.
numberThe gap between indicator and track, in dp.
strokeWidthnumberThe line width, in dp. Circular.
numberThe line width, in dp. Circular.
drawStopIndicatorComposeProgressStopIndicatorThe end dot of a determinate linear bar: { color, strokeCap, stopSize }.
ComposeProgressStopIndicatorThe end dot of a determinate linear bar: { color, strokeCap, stopSize }.
stopSizenumberThe end dot size, in dp. Linear wavy.
numberThe end dot size, in dp. Linear wavy.
amplitudenumberThe wave height. Wavy.
numberThe wave height. Wavy.
wavelengthnumberThe wave length, in dp. Wavy.
numberThe wave length, in dp. Wavy.
waveSpeednumberHow fast the wave moves. Wavy.
numberHow fast the wave moves. Wavy.

LoadingIndicator and ContainedLoadingIndicator are the Material 3 expressive loading shapes, with progress and color; the contained one adds containerColor.

LoadingIndicatorTypeDescription
progressnumber | nullFrom 0 to 1. Unset animates.
number | nullFrom 0 to 1. Unset animates.
colorColorValueThe shape color.
ColorValueThe shape color.

LazyColumn, LazyRow

One.Android.LazyColumn scrolls children vertically and One.Android.LazyRow horizontally. Children become lazy items: only the visible window composes, so long lists stay cheap. Give the list a bounded height (column) or width (row) through composeStyle; items size themselves.

<One.Android.LazyColumn
style={{ height: 320 }}
verticalArrangement={{ spacedBy: 8 }}
contentPadding={{ top: 8, bottom: 8 }}
>
{items.map((item) => (
<One.Android.Text key={item.id} text={item.title} />
))}
</One.Android.LazyColumn>
LazyColumnTypeDescription
verticalArrangementComposeVerticalArrangement | Readonly<{ spacedBy: number }>A preset, or { spacedBy } for a gap in dp.
ComposeVerticalArrangement | Readonly<{ spacedBy: number }>A preset, or { spacedBy } for a gap in dp.
horizontalAlignment'start' | 'end' | 'center' = 'start'How items sit across the column.
'start' | 'end' | 'center' = 'start'How items sit across the column.
contentPaddingComposeLazyContentPaddingInset around the items, in dp.
ComposeLazyContentPaddingInset around the items, in dp.
LazyRowTypeDescription
horizontalArrangementComposeHorizontalArrangement | Readonly<{ spacedBy: number }>A preset, or { spacedBy } for a gap in dp.
ComposeHorizontalArrangement | Readonly<{ spacedBy: number }>A preset, or { spacedBy } for a gap in dp.
verticalAlignment'top' | 'bottom' | 'center' = 'top'How items sit across the row.
'top' | 'bottom' | 'center' = 'top'How items sit across the row.
contentPaddingComposeLazyContentPaddingInset around the items, in dp.
ComposeLazyContentPaddingInset around the items, in dp.
LazyContentPaddingTypeDescription
startnumberLeading inset, in dp.
numberLeading inset, in dp.
topnumberTop inset, in dp.
numberTop inset, in dp.
endnumberTrailing inset, in dp.
numberTrailing inset, in dp.
bottomnumberBottom inset, in dp.
numberBottom inset, in dp.

Image

One.Android.Image draws a bundled asset or a URI through Compose. Size it with composeStyle width and height; the bitmap scales inside those bounds.

<One.Android.Image
source={{ uri: fileUri }}
contentScale="crop"
contentDescription="A mountain at sunset"
composeStyle={{ width: 160, height: 100 }}
onLoad={() => setLoaded(true)}
onError={(error) => setError(error)}
/>
ImageTypeDescription
source (required)ComposeImageSourceA bundled asset id or { uri }.
ComposeImageSourceA bundled asset id or { uri }.
contentScaleComposeImageContentScale = 'fit'fit, crop, fillBounds, fillWidth, fillHeight, inside, or none.
ComposeImageContentScale = 'fit'fit, crop, fillBounds, fillWidth, fillHeight, inside, or none.
alignmentComposeContentAlignment = 'center'Where the image sits inside its bounds.
ComposeContentAlignment = 'center'Where the image sits inside its bounds.
contentDescriptionstring | nullSpoken to screen readers. Null marks a decorative image.
string | nullSpoken to screen readers. Null marks a decorative image.
tintColorValueA color applied to every non-transparent pixel.
ColorValueA color applied to every non-transparent pixel.
alphanumberOpacity, from 0 to 1.
numberOpacity, from 0 to 1.
onLoad() => voidThe image decoded and drew.
() => voidThe image decoded and drew.
onError(message: string) => voidThe image failed to load, with the reason.
(message: string) => voidThe image failed to load, with the reason.

Snackbar

One.Android.SnackbarHost shows Material 3 snackbars. Its ref exposes showSnackbar, which resolves 'actionPerformed' when the user taps the action and 'dismissed' when the snackbar times out or is dismissed. Calls queue behind the visible snackbar. A One.Android.Snackbar child styles the shown snackbars.

const host = useRef<ComposeSnackbarHostRef>(null)
<One.Android.SnackbarHost ref={host}>
<One.Android.Snackbar containerColor="#1b1b1f" />
</One.Android.SnackbarHost>
await host.current?.showSnackbar({ message: 'File saved', actionLabel: 'Undo' })
SnackbarHostTypeDescription
childrenReactNodeThe host content, including one Snackbar that styles the shown snackbars.
ReactNodeThe host content, including one Snackbar that styles the shown snackbars.
accessibilityRoleComposeAccessibilityRoleThe accessibility role.
ComposeAccessibilityRoleThe accessibility role.
styleStyleProp<ViewStyle>The outer style. Nested nodes use composeStyle instead.
StyleProp<ViewStyle>The outer style. Nested nodes use composeStyle instead.
composeStyleComposeStyleCompose layout for this node.
ComposeStyleCompose layout for this node.
SnackbarTypeDescription
containerColorColorValueThe snackbar background.
ColorValueThe snackbar background.
contentColorColorValueThe message text color.
ColorValueThe message text color.
actionColorColorValueThe action button container color.
ColorValueThe action button container color.
actionContentColorColorValueThe action button label color.
ColorValueThe action button label color.
dismissActionContentColorColorValueThe dismiss icon color.
ColorValueThe dismiss icon color.
actionOnNewLineboolean = falsePuts a long action label under the message.
boolean = falsePuts a long action label under the message.
SnackbarShowOptionsTypeDescription
message (required)stringThe message body.
stringThe message body.
actionLabelstringThe action button label. No button when unset.
stringThe action button label. No button when unset.
withDismissActionboolean = falseShows a trailing close button.
boolean = falseShows a trailing close button.
durationComposeSnackbarDurationshort, long, or indefinite. Short without an action, indefinite with one.
ComposeSnackbarDurationshort, long, or indefinite. Short without an action, indefinite with one.

ModalBottomSheet

One.Android.ModalBottomSheet presents its children in a Material 3 modal sheet. Mounting shows it; onDismissRequest fires on a swipe, back press, or scrim tap, and the parent unmounts it. The ref hides the sheet with an animation through hide, which resolves when the sheet is hidden.

const [open, setOpen] = useState(false)
const sheet = useRef<ComposeModalBottomSheetRef>(null)
{open ? (
<One.Android.ModalBottomSheet onDismissRequest={() => setOpen(false)}>
<One.Android.Text text="Sheet body" />
</One.Android.ModalBottomSheet>
) : null}
ModalBottomSheetTypeDescription
onDismissRequest (required)() => voidA swipe, back press, or scrim tap asked to close it.
() => voidA swipe, back press, or scrim tap asked to close it.
skipPartiallyExpandedboolean = falseOpens the sheet full screen.
boolean = falseOpens the sheet full screen.
initialFullyExpandedboolean = falseStarts fully expanded. Ignored with skipPartiallyExpanded.
boolean = falseStarts fully expanded. Ignored with skipPartiallyExpanded.
scrimColorColorValueThe overlay behind the sheet.
ColorValueThe overlay behind the sheet.
showDragHandleboolean = trueShows the default handle. Ignored with a DragHandle slot.
boolean = trueShows the default handle. Ignored with a DragHandle slot.
sheetGesturesEnabledboolean = trueSwipe to dismiss and drag gestures.
boolean = trueSwipe to dismiss and drag gestures.
propertiesComposeModalBottomSheetPropertiesBack press and scrim dismissal behavior.
ComposeModalBottomSheetPropertiesBack press and scrim dismissal behavior.
ModalBottomSheetPropertiesTypeDescription
shouldDismissOnClickOutsideboolean = trueA scrim tap calls onDismissRequest.
boolean = trueA scrim tap calls onDismissRequest.

A custom drag handle replaces the default one:

<One.Android.ModalBottomSheet onDismissRequest={close}>
<One.Android.ModalBottomSheet.DragHandle>
<One.Android.Text text="Grabber" />
</One.Android.ModalBottomSheet.DragHandle>
<One.Android.Text text="Sheet body" />
</One.Android.ModalBottomSheet>

One.Android.NavigationBar is the Material 3 bottom bar. Its children are One.Android.NavigationBarItem destinations, which spread evenly across the bar. The parent owns selection: each item reports selected, and onClick moves it.

const [tab, setTab] = useState('home')
<One.Android.NavigationBar>
<One.Android.NavigationBarItem
selected={tab === 'home'}
onClick={() => setTab('home')}
label="Home"
icon="home"
/>
<One.Android.NavigationBarItem
selected={tab === 'search'}
onClick={() => setTab('search')}
label="Search"
icon="search"
/>
</One.Android.NavigationBar>
NavigationBarTypeDescription
containerColorColorValueThe bar background.
ColorValueThe bar background.
contentColorColorValueThe default icon and label color.
ColorValueThe default icon and label color.
tonalElevationnumberThe tonal elevation, in dp.
numberThe tonal elevation, in dp.
NavigationBarItemTypeDescription
selected (required)booleanThis destination is the current one.
booleanThis destination is the current one.
onClick (required)() => voidThe item was tapped.
() => voidThe item was tapped.
labelstringThe text under the icon.
stringThe text under the icon.
icon (required)ComposeIconNameA Material Symbols icon name.
ComposeIconNameA Material Symbols icon name.
iconFilledboolean = falseUses the filled icon font.
boolean = falseUses the filled icon font.
enabledboolean = trueA disabled item ignores taps.
boolean = trueA disabled item ignores taps.
alwaysShowLabelboolean = trueShows the label when unselected.
boolean = trueShows the label when unselected.
colorsComposeNavigationBarItemColorsIcon, label and indicator colors.
ComposeNavigationBarItemColorsIcon, label and indicator colors.
NavigationBarItemColorsTypeDescription
selectedIconColorColorValueThe selected icon color.
ColorValueThe selected icon color.
selectedTextColorColorValueThe selected label color.
ColorValueThe selected label color.
indicatorColorColorValueThe selection pill color.
ColorValueThe selection pill color.
unselectedIconColorColorValueThe unselected icon color.
ColorValueThe unselected icon color.
unselectedTextColorColorValueThe unselected label color.
ColorValueThe unselected label color.
disabledIconColorColorValueThe disabled icon color.
ColorValueThe disabled icon color.
disabledTextColorColorValueThe disabled label color.
ColorValueThe disabled label color.

SearchBar, DockedSearchBar

One.Android.SearchBar is the Material 3 search field. query is controlled text, expanded opens the results list, and children render as the expanded content. onSearch fires when the user submits the query. Leading and trailing icons go in slots; the M3 pattern swaps the leading search icon for a back arrow while expanded. One.Android.DockedSearchBar shares the same props, and its results anchor under the field instead of taking the screen.

const [query, setQuery] = useState('')
const [expanded, setExpanded] = useState(false)
<One.Android.SearchBar
query={query}
onQueryChange={setQuery}
expanded={expanded}
onExpandedChange={setExpanded}
placeholder="Search items"
onSearch={(submitted) => runSearch(submitted)}
>
<One.Android.SearchBar.LeadingIcon>
<One.Android.Icon name="search" />
</One.Android.SearchBar.LeadingIcon>
{results.map((result) => (
<One.Android.Text key={result.id} text={result.title} />
))}
</One.Android.SearchBar>
SearchBar, DockedSearchBarTypeDescription
query (required)stringThe controlled search text.
stringThe controlled search text.
onQueryChange (required)(value: string) => voidThe text changed.
(value: string) => voidThe text changed.
revisionnumberBump to force the native text to the query.
numberBump to force the native text to the query.
expanded (required)booleanThe results list is open.
booleanThe results list is open.
onExpandedChange (required)(expanded: boolean) => voidA tap or back press asked to expand or collapse.
(expanded: boolean) => voidA tap or back press asked to expand or collapse.
expandedRevisionnumberBump to force native expansion to expanded.
numberBump to force native expansion to expanded.
placeholderstringThe hint shown when the query is empty.
stringThe hint shown when the query is empty.
enabledboolean = trueA disabled bar ignores input.
boolean = trueA disabled bar ignores input.
onSearch(query: string) => voidThe user submitted the query.
(query: string) => voidThe user submitted the query.
containerColorColorValueThe bar background.
ColorValueThe bar background.

One.Android.DropdownMenu is the Material 3 popup menu. Put it beside its anchor in a Box; its children are One.Android.DropdownMenuItem rows. The parent owns expansion: expanded opens it, and onDismissRequest fires on an outside tap or back press. One.Android.ExposedDropdownMenuBox is the anchored text-field form: a read-only field shows value, tapping it opens the same items, and picking one usually writes the value and collapses.

const [open, setOpen] = useState(false)
<One.Android.Box>
<One.Android.Button label="Open menu" onPress={() => setOpen(true)} />
<One.Android.DropdownMenu expanded={open} onDismissRequest={() => setOpen(false)}>
<One.Android.DropdownMenuItem text="Edit" onClick={() => edit()} leadingIcon="edit" />
<One.Android.DropdownMenuItem text="Share" onClick={() => share()} leadingIcon="share" />
</One.Android.DropdownMenu>
</One.Android.Box>
<One.Android.ExposedDropdownMenuBox
expanded={boxOpen}
onExpandedChange={setBoxOpen}
value={size}
placeholder="Size"
>
{['Small', 'Medium', 'Large'].map((option) => (
<One.Android.DropdownMenuItem
key={option}
text={option}
onClick={() => {
setSize(option)
setBoxOpen(false)
}}
/>
))}
</One.Android.ExposedDropdownMenuBox>
DropdownMenuTypeDescription
expanded (required)booleanThe menu is open.
booleanThe menu is open.
onDismissRequest (required)() => voidAn outside tap or back press asked to close it.
() => voidAn outside tap or back press asked to close it.
containerColorColorValueThe menu background.
ColorValueThe menu background.
DropdownMenuItemTypeDescription
text (required)stringThe row label.
stringThe row label.
onClick (required)() => voidThe row was tapped.
() => voidThe row was tapped.
enabledboolean = trueA disabled row ignores taps.
boolean = trueA disabled row ignores taps.
leadingIconComposeIconNameA Material Symbols icon before the label.
ComposeIconNameA Material Symbols icon before the label.
trailingIconComposeIconNameA Material Symbols icon after the label.
ComposeIconNameA Material Symbols icon after the label.
iconFilledboolean = falseUses the filled icon font.
boolean = falseUses the filled icon font.
colorsComposeDropdownMenuItemColorsLabel and icon colors.
ComposeDropdownMenuItemColorsLabel and icon colors.
DropdownMenuItemColorsTypeDescription
textColorColorValueThe label color.
ColorValueThe label color.
leadingIconColorColorValueThe leading icon color.
ColorValueThe leading icon color.
trailingIconColorColorValueThe trailing icon color.
ColorValueThe trailing icon color.
disabledTextColorColorValueThe disabled label color.
ColorValueThe disabled label color.
disabledLeadingIconColorColorValueThe disabled leading icon color.
ColorValueThe disabled leading icon color.
disabledTrailingIconColorColorValueThe disabled trailing icon color.
ColorValueThe disabled trailing icon color.
ExposedDropdownMenuBoxTypeDescription
expanded (required)booleanThe menu is open.
booleanThe menu is open.
onExpandedChange (required)(expanded: boolean) => voidA tap, outside tap, or back press asked to expand or collapse.
(expanded: boolean) => voidA tap, outside tap, or back press asked to expand or collapse.
expandedRevisionnumberBump to force native expansion to expanded.
numberBump to force native expansion to expanded.
value (required)stringThe read-only text in the field.
stringThe read-only text in the field.
placeholderstringThe hint shown when the value is empty.
stringThe hint shown when the value is empty.
enabledboolean = trueA disabled box ignores taps.
boolean = trueA disabled box ignores taps.

PullToRefreshBox

One.Android.PullToRefreshBox wraps scrollable children with the Material 3 pull gesture and indicator. A pull past the threshold calls onRefresh; the parent keeps isRefreshing true until its reload finishes. Give the box a bounded height so its list can scroll.

const [refreshing, setRefreshing] = useState(false)
<One.Android.PullToRefreshBox
isRefreshing={refreshing}
onRefresh={() => void reload().finally(() => setRefreshing(false))}
composeStyle={{ height: 320, fillMaxWidth: true }}
>
<One.Android.LazyColumn>
{items.map((item) => (
<One.Android.Text key={item.id} text={item.title} />
))}
</One.Android.LazyColumn>
</One.Android.PullToRefreshBox>
PullToRefreshBoxTypeDescription
isRefreshing (required)booleanA reload is running; the indicator spins.
booleanA reload is running; the indicator spins.
onRefresh (required)() => voidA pull past the threshold asked for a reload.
() => voidA pull past the threshold asked for a reload.
enabledboolean = trueA disabled box ignores pulls.
boolean = trueA disabled box ignores pulls.

TooltipBox

One.Android.TooltipBox shows a Material 3 tooltip on long-press over its children. A title upgrades the plain tooltip to the rich form.

<One.Android.TooltipBox text="Save the file">
<One.Android.IconButton onClick={() => save()}>
<One.Android.Icon name="save" />
</One.Android.IconButton>
</One.Android.TooltipBox>
TooltipBoxTypeDescription
text (required)stringThe tooltip body.
stringThe tooltip body.
titlestringA title, which selects the rich tooltip.
stringA title, which selects the rich tooltip.
enabledboolean = trueA disabled box ignores long-presses.
boolean = trueA disabled box ignores long-presses.

AnimatedVisibility

One.Android.AnimatedVisibility fades and resizes its children in and out as visible changes. enter and exit pick one transition each; unset, both use the Material fade with a vertical resize.

<One.Android.AnimatedVisibility visible={open} enter="expandVertically" exit="fade">
<One.Android.Text text="Now you see me" />
</One.Android.AnimatedVisibility>
AnimatedVisibilityTypeDescription
visible (required)booleanThe children are shown.
booleanThe children are shown.
enterComposeAnimatedVisibilityTransitionfade, scale, slideVertically, or expandVertically.
ComposeAnimatedVisibilityTransitionfade, scale, slideVertically, or expandVertically.
exitComposeAnimatedVisibilityTransitionfade, scale, slideVertically, or expandVertically. The slide and expand forms shrink on exit.
ComposeAnimatedVisibilityTransitionfade, scale, slideVertically, or expandVertically. The slide and expand forms shrink on exit.

Custom dialog content

One.Android.BasicAlertDialog mounts a Material 3 dialog while it is in the React tree. Its optional onDismissRequest reports back or outside taps; remove the component to close it. children supplies the content. The properties object accepts dismissOnBackPress, dismissOnClickOutside, usePlatformDefaultWidth, and decorFitsSystemWindows, all defaulting to true. Unlike the existing Dialog, this SDK surface has no visible prop.

import { useState } from 'react'
import { One } from 'one'
function CustomDialog() {
const [open, setOpen] = useState(true)
return open && (
<One.Android.BasicAlertDialog onDismissRequest={() => setOpen(false)}>
<One.Android.Column composeStyle={{ padding: 24, backgroundColor: '#ffffff' }}>
<One.Android.Text text="Custom dialog content" />
<One.Android.Button label="Close" onPress={() => setOpen(false)} />
</One.Android.Column>
</One.Android.BasicAlertDialog>
)
}

Material carousels

Carousel is a family of three components:

ComponentSize inputs
HorizontalCenteredHeroCarouselOptional maxItemWidth, minSmallItemWidth, maxSmallItemWidth
HorizontalMultiBrowseCarouselRequired preferredItemWidth; optional minSmallItemWidth, maxSmallItemWidth
HorizontalUncontainedCarouselRequired itemWidth

Each direct Compose child is an item. All three accept itemSpacing (dp, zero by default), contentPadding (dp or { start, top, end, bottom }), flingBehavior (singleAdvance or noSnap), and userScrollEnabled (default true). Hero and multi-browse default to single-item snapping; uncontained defaults to free scrolling. Widths must be positive, and spacing and padding must be nonnegative. Use a finite height for the carousel.

import { One } from 'one'
const items = [{ id: 'first', title: 'First item' }, { id: 'second', title: 'Second item' }]
const example = (
<One.Android.HorizontalUncontainedCarousel itemWidth={180} itemSpacing={8} style={{ height: 120 }}>
{items.map(item => (
<One.Android.Box key={item.id} composeStyle={{ height: 120, fillMaxWidth: true }}>
<One.Android.Text text={item.title} />
</One.Android.Box>
))}
</One.Android.HorizontalUncontainedCarousel>
)

Date ranges

DateRangePicker and DateRangePickerDialog accept optional initialStartDate and initialEndDate ISO strings. Omit both for an empty selection, or omit the end for a partial range. An end requires a start and must fall on or after it. Dates are calendar days represented at UTC midnight. selectableDates={{ start, end }} accepts optional Date bounds. Initial selections must fall within these bounds.

Both accept variant (picker or input), showVariantToggle, showTitle, showHeadline (all three booleans default to true), color, and elementColors with the existing DatePicker color keys. onDateRangeSelected({ start, end }) receives Date | null for each endpoint. The inline picker reports its initial range and each selection change. The dialog reports only a confirmed complete range. The dialog requires onDismissRequest and accepts confirmButtonLabel and dismissButtonLabel, which default to system labels. Mount and unmount the dialog to present and close it; an incomplete selection disables confirmation.

import { One } from 'one'
const setRange = (range: { start: Date | null; end: Date | null }) => console.log(range)
const example = (
<One.Android.DateRangePicker
initialStartDate="2026-10-12"
initialEndDate="2026-10-14"
onDateRangeSelected={setRange}
style={{ height: 500 }}
/>
)

Floating toolbar

HorizontalFloatingToolbar lays out Compose children in a Material toolbar. variant is standard (default) or vibrant. Its optional colors object accepts toolbarContainerColor, toolbarContentColor, fabContainerColor, and fabContentColor. Unset fields use the variant’s defaults. Put the optional FAB content inside HorizontalFloatingToolbar.FloatingActionButton, whose optional onPress receives its native click.

import { One } from 'one'
const edit = () => console.log('edit')
const add = () => console.log('add')
const example = (
<One.Android.HorizontalFloatingToolbar variant="vibrant">
<One.Android.IconButton onClick={edit}><One.Android.Icon name="edit" /></One.Android.IconButton>
<One.Android.HorizontalFloatingToolbar.FloatingActionButton onPress={add}>
<One.Android.Icon name="add" />
</One.Android.HorizontalFloatingToolbar.FloatingActionButton>
</One.Android.HorizontalFloatingToolbar>
)

Shapes

One.Android.Shape provides Star, PillStar, Pill, Circle, Rectangle, Polygon, and RoundedCorner. Shapes are leaves; give them explicit size through style at the root or composeStyle inside a Compose tree. color defaults to transparent. cornerRounding, smoothing, innerRadius, and radius are fractions from zero to one. verticesCount is an integer of at least three (default six). cornerRounding and smoothing default to zero; radius and innerRadius default to zero. Set radius={1} for a full-size circle or star. Stars use the two radii; polygons use the vertex count. Pill uses smoothing, Circle uses radius and vertex count, and Rectangle uses corner rounding and smoothing. RoundedCorner uses cornerRadii={{ topStart, topEnd, bottomStart, bottomEnd }} in dp, with omitted corners zero. Logical corners follow layout direction.

import { One } from 'one'
const example = (
<One.Android.Shape.Polygon color="#d24c30" verticesCount={5} cornerRounding={0.1} style={{ width: 80, height: 80 }} />
)

Synchronous switches

SyncSwitch accepts isOn={state} from useNativeState(false), optional enabled (default true), and optional onCheckedChangeSync. The callback must contain the 'worklet' directive. Native Compose reads and writes the shared boolean directly; all bound switches observe the same entry. The callback runs synchronously on the worklets UI runtime after a native change. Programmatic writes and disabled switches do not invoke it. The existing Switch remains the scalar isOn/onIsOnChange control.

import { One, useNativeState } from 'one'
import { useSharedValue } from 'react-native-reanimated'
function NotificationsSwitch() {
const isOn = useNativeState(false)
const lastChange = useSharedValue(false)
return <One.Android.SyncSwitch isOn={isOn} onCheckedChangeSync={value => {
'worklet'
lastChange.value = value
}} />
}

These APIs are Android-only and use One’s existing style and composeStyle props. Their SDK behavioral contracts are preserved; a modifiers array is not an input to One’s Compose tree. Native feature acceptance is tracked separately from adapter validation.

Edit this page on GitHub.