Patterns from production · Layout that holds
On a phone, New is a floating button over a sheet
Adding is one button; its choices wait in a sheet.
On a phone, New is a floating button over a sheet
Try the controls to see the rule.
The rule
A page whose main act is adding (files, posts, worlds) puts New in a floating button above the tab bar. It opens a sheet from the bottom with the two or three ways to add; a tap outside, Escape or Back closes it. On a computer the same New sits at the top of the sidebar and opens a small card.
Tokens used
size.tap44pxmotion.duration.base260msmotion.easing.standardcubic-bezier(.2,.7,.2,1)space.md12px
Native spec · generated from this pattern and the shared token registry
struct OvFabSheet: View {
let status: String
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View {
HStack(spacing: OvScale.spaceMd) {
Text(status).font(.body)
}
.frame(minHeight: OvScale.sizeTap)
.animation(reduceMotion ? .none : .easeOut(duration: OvScale.motionDurationBase), value: status)
}
}
// Tokens: size.tap=44px, motion.duration.base=260ms, motion.easing.standard=cubic-bezier(.2,.7,.2,1), space.md=12px@Composable
fun OvFabSheet(status: String, reduceMotion: Boolean) {
Row(
modifier = Modifier.defaultMinSize(minHeight = OvScale.SizeTap),
horizontalArrangement = Arrangement.spacedBy(OvScale.SpaceMd),
) {
Text(status, style = MaterialTheme.typography.bodyMedium)
}
// Apply motion only when !reduceMotion.
}
// Tokens: size.tap=44px, motion.duration.base=260ms, motion.easing.standard=cubic-bezier(.2,.7,.2,1), space.md=12px