Surface for lower-priority interactive content that needs a secondary surface treatment. It builds on InteractableBase and adds a semantic corner radius, a flat background fill, and stacked inner-shadow overlays for focus and press feedback. The toolkit owns those interaction visuals so focus and activation remain consistent. Surface does not render a ContainerMaterial, use a shape provider, or draw smooth corners.Container for primary interactive content, StaticContainer for non-interactive material rendering, and Panel for an informational backdrop. Surface is typically needed only when those components do not express the intended secondary interaction. Follow the same supported-composition boundaries as Container, and use the large spacing token around non-full-bleed content.Surface is interactive by default. A plain instance receives focus, shows press feedback, and activates as a control:import {Surface, SurfaceCornerRadius, TextView, TextStyle} from '@wearables-ui-toolkit/mrbd';
function SecondaryDetails() {
return (
<Surface
cornerRadius={SurfaceCornerRadius.MEDIUM}
ariaLabel="Secondary details"
onActivate={openSecondaryDetails}
>
<TextView className="surface-content" textStyle={TextStyle.BODY1}>
Secondary details
</TextView>
</Surface>
);
}
.surface-content {
padding: var(--uit-spacing-large);
}
StaticContainer or Panel. When the visual treatment specifically requires Surface, set interactive={false} so it does not enter focus or directional navigation:import {Surface, SurfaceCornerRadius} from '@wearables-ui-toolkit/mrbd';
<Surface
interactive={false}
cornerRadius={SurfaceCornerRadius.SMALL}
drawBackground={false}
>
<PreviewMedia />
</Surface>;
Surface renders a div and forwards its ref to that element. In addition to its own props, it accepts the complete InteractableBase prop surface, including capability switches, activation callbacks, tooltip props, partial-focus props, and standard DOM attributes. The toolkit forwards these to the root. The full prop type is SurfaceProps.| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Content rendered in a centered wrapper that fills the surface. |
cornerRadius | SurfaceCornerRadius | SurfaceCornerRadius.XSMALL | Semantic corner radius. Bare numbers are not accepted. |
drawBackground | boolean | true | Renders the background fill layer. |
width | number \| string | 'auto' | CSS width. A number is treated as pixels; prefer intrinsic or responsive values. |
height | number \| string | 'auto' | CSS height, with the same rules as width. |
contentScaleForStateFn | (state, size) => number | app platform profile | Overrides the content-scale policy. |
className | string | '' | Class added alongside the component’s root class. |
style | CSSProperties | — | Inline styles merged over the surface’s root styles. They can override size, radius, opacity, and transform. |
| Prop | Type | Default | Description |
|---|---|---|---|
interactive | boolean | true | Master switch for focusable, pressable, and clickable. Set it to false for a visual-only surface. |
focusable | boolean | value of interactive | Controls whether the surface receives focus. |
pressable | boolean | value of interactive | Controls whether the surface shows press feedback. |
clickable | boolean | value of interactive | Controls whether activation runs. |
disabled | boolean | false | Blocks activation and applies disabled opacity while keeping the surface focusable. |
onActivate | (event: InteractableActivationEvent) => void | — | Runs once per activation. |
onStateChange | (prev: InteractionState, next: InteractionState) => void | — | Runs after Surface applies its own state change. |
ariaLabel | string | — | Accessible name. |
role | string | 'button' when clickable | Overrides the role when the surface is not a button. |
tooltipMode | TooltipMode | TooltipMode.NONE | Enables the tooltip. Other tooltip* props behave as documented on the base. |
SurfaceCornerRadius is a closed set of semantic radii from smallest to largest. Bare numbers are not assignable, which keeps every surface on the same shape scale instead of creating per-instance radii.| Member | Value |
|---|---|
SurfaceCornerRadius.XXSMALL | 'xxsmall' |
SurfaceCornerRadius.XSMALL | 'xsmall' |
SurfaceCornerRadius.SMALL | 'small' |
SurfaceCornerRadius.MEDIUM | 'medium' |
SurfaceCornerRadius.LARGE | 'large' |
SurfaceCornerRadius.XLARGE | 'xlarge' |
Surface inherits the default interactive behavior. A bare instance is focusable, pressable, and clickable, and its div root receives the button role. Set interactive={false} for a static surface so it does not advertise control behavior.drawBackground={false} removes only the fill; the inner shadows continue to respond to interaction state.Container, Surface reads the platform profile supplied by App and scales the whole surface slightly inward at rest, opens it to full size on focus, and insets it again on press. Applications do not pass a platform value to individual surfaces. The scale comes from an explicit numeric width when present, otherwise from the measured width. Until the toolkit knows the real size, the surface remains at full size instead of estimating.cornerRadius to a semantic token and applies the resulting plain CSS radius to the root, fill, and both inner shadows. The root clips its content, so the surface rounds full-bleed children consistently.var(--uit-enabled-opacity) to var(--uit-disabled-opacity) and blocks activation. The element remains focusable so directional navigation preserves its layout structure.width or height provides another size. Its content wrapper centers children on both axes. The toolkit writes size, radius, opacity, and content-scale transform inline, so a CSS class cannot change them; use the corresponding props or style.Surface has no material or shapeProvider prop, smooth corner path, or partial-focus material origin. Prefer Container when the design requires material behavior.Surface renders as a div with role="button" and a tab index. It activates on click and with Enter or Space. Provide an ariaLabel when visible content does not already name the action, so assistive technology exposes a clear target.div; callers cannot replace it with a built-in HTML element. When the surface represents something other than a button, the application must set the correct role and provide every ARIA state required by that role. For content that only needs visual grouping, set interactive={false} so the surface leaves directional navigation and exposes no control role.aria-hidden, keeping these decorative visuals out of the accessibility tree.Surface for lower-priority interactive content that specifically needs a secondary surface treatment.SurfaceCornerRadius value and semantic spacing tokens for its content so shape and rhythm remain consistent.interactive={false} when the surface is visual rather than a control, so it does not create a misleading focus stop.Container or a higher-level component whenever it already expresses the intended interface and behavior.StaticContainer or Panel; otherwise set interactive={false} explicitly.Surface. These components each own their focus, interaction, or surface behavior, so the composition is unsupported.Surface as a flat secondary treatment. It has no shape provider, smooth corners, or partial-focus material response; use Container for those capabilities.style with a radius outside the semantic cases. Choose a supported SurfaceCornerRadius so adjacent surfaces remain consistent.