Corner radius

Updated: Sep 24, 2026
Choose radius from the semantic scale and apply it through component APIs. The toolkit surfaces use smooth corner geometry rather than a plain circular arc, and the material fill, glow, stroke, scrim, and content clip all follow the same path.

The scale

Nine steps, declared at the document root by the library stylesheet:
TokenPosition in the scale
--uit-corner-radius-xxsmall
Tightest rounding; small indicators and inset artwork.
--uit-corner-radius-xsmall
Compact surfaces and media inset inside a larger surface.
--uit-corner-radius-small
Small tiles and controls.
--uit-corner-radius-medium
Ordinary content surfaces.
--uit-corner-radius-large
Larger panels and cards.
--uit-corner-radius-xlarge
Prominent, near-full-width surfaces.
--uit-corner-radius-2xlarge
Very large surfaces where the curve is part of the shape’s character.
--uit-corner-radius-3xlarge
The largest fixed step; surfaces that read as nearly capsule-shaped.
--uit-corner-radius-full
Pill and circular shapes, whatever the element’s size.
Use full for pills and circles. Use the ordinal steps for everything else, choosing the step that matches the surface’s weight in the hierarchy. The radius steps do not correspond one-to-one to the spacing steps of the same name, and a component that already owns a radius is the authority on which step it uses.
The two largest fixed steps are spelled 2xlarge and 3xlarge as CSS tokens and XXLARGE and XXXLARGE as CornerRadius members; they are the same two steps under two spellings.

Choosing a radius through a component

Components that let you pick a shape expose a closed enum rather than a length.
EnumMembersUsed by
SurfaceCornerRadius
XXSMALL, XSMALL, SMALL, MEDIUM, LARGE, XLARGE
Surface
ShimmerItemCornerRadius
SQUARE, XXSMALL, XSMALL, SMALL, MEDIUM, LARGE, XLARGE
ShimmerItem
CornerRadius
XXSMALL, XSMALL, SMALL, MEDIUM, LARGE, XLARGE, XXLARGE, XXXLARGE, FULL
RoundedRectangleShapeProvider and TailShapeProvider
Surface and ShimmerItem already default to a step — SurfaceCornerRadius.XSMALL and ShimmerItemCornerRadius.MEDIUM respectively — so pass a radius only when the shape has to differ from that default.
import { Surface, SurfaceCornerRadius, TextStyle, TextView } from '@wearables-ui-toolkit/mrbd';

<Surface cornerRadius={SurfaceCornerRadius.MEDIUM}>
  <TextView textStyle={TextStyle.BODY2}>Signal acquired</TextView>
</Surface>
ShimmerItemCornerRadius.SQUARE is the only unrounded option in the system, and it exists so a loading placeholder can match an unrounded element it stands in for.
CornerRadius is a branded numeric type: its members are the only values a shape provider accepts, so an arbitrary number will not type-check. The generated CSS custom properties and TypeScript geometry values come from the same token definitions, keeping CSS fallbacks and smooth paths on one fixed scale. Use the custom properties in application CSS, but do not redefine them.
When a material needs a shape, build a shape provider from a CornerRadius member and memoize it, so the cached geometry stays valid across renders.
import { useMemo, type ReactNode } from 'react';
import { Container, CornerRadius, RoundedRectangleShapeProvider } from '@wearables-ui-toolkit/mrbd';

function Tile({ children }: { children: ReactNode }) {
  const shapeProvider = useMemo(
    () => new RoundedRectangleShapeProvider(CornerRadius.LARGE),
    [],
  );

  return <Container shapeProvider={shapeProvider}>{children}</Container>;
}

Concentric rounding

Keep an inset rounded element’s corners concentric with its parent after accounting for the inset. Derive the relationship from the tokens you already used for the inset instead of picking a radius that happens to look right at one size — the two shapes drift apart as soon as the layout changes.
Inset media inside a modal is the common case: the modal owns the outer radius, the inset uses a spacing token, and the media’s radius follows from both. The inner radius is always the smaller of the two; an inner shape rounded as much as its parent will visibly collide with the parent’s curve at the corners.
  • Choose radius through the component’s shape enum whenever one exists so the component owns its complete geometry.
  • Keep every layer of a surface—fill, stroke, glow, scrim, and clip—on one shape.
  • Reuse and memoize shape providers so geometry caches stay effective.
  • Use full for a pill instead of an arbitrarily large fixed step.

Avoid

  • Use the component shape API rather than border-radius to reproduce smooth corners, tails, avatar cutouts, panel shapes, or focus outlines.
  • Prefer one rounded surface. Nesting another material only for padding doubles the visual boundary.
  • Customize through public shape props rather than a component’s internal radius.
  • Create shape providers outside render so identity and caches remain stable.