# Placing and naming a component — m:, w:, grow:, alignSelf:, animation:, label: on a component call

> A caller may PLACE, SPACE and ANIMATE a component it calls — `m*`, `w`/`h` and their min/max, `grow`, `shrink`, `basis`, `alignSelf`, `order`, `colSpan`/`rowSpan`/`gridArea`, `animation`, `animationDelay`, `exitAnimation` and `animationKey` — and they apply to the component's root element, winning over its own. What PAINTS it (colour, border, type) stays the component's own vocabulary, such as `tone:` and `size:`. A caller may also NAME it — `label:` becomes the root's accessible name, and what a test's `within:` finds it by.

<!-- id: ui-component-root-style · area: ui · stability: stable · html: https://osysharp.com/reference/ui/component-root-style/ -->

## Summary        {#summary}

Where a component sits, how much room it gets and how it arrives are decisions about the page around it, so the
caller writes them on the call:

```osy title="placing kit controls from the page" test app=ui-component-root-style
[Route("/orders")] [AllowAnonymous]
component OrdersPage() {
  int fresh = 3;
  render {
    Row(gap: 2, align: Align.Center) {
      Text("Orders", grow: 1);
      Badge($"{fresh} new", tone: Tone.Primary, ml: 2, animationKey: fresh);
      Button("Refresh", onPress: Refresh, alignSelf: AlignSelf.End);
    }
  }
  action Refresh() { fresh = fresh + 1; }
}
```

## Signature      {#signature}

```osy syntax
<Component>(<args>…, <placement prop>: <value>)
// m mx my mt mb ml mr · w h minW maxW minH maxH · grow shrink basis alignSelf order colSpan rowSpan gridArea
// animation animationDelay exitAnimation animationKey · label
```

The values are the ones the same prop takes on an atom ([style props](https://osysharp.com/reference/ui/styling/)): spacing steps, lengths, enum members,
declared animations.

## Description    {#description}

### Which element do they land on?   {#root}

The component's ROOT — the element its `render` writes at the top level. A component whose root is another
component passes them on, so `Badge(…)` inside your own `[Composable] component Status` takes the `m:` written on
`Status(…, m: 2)`. Each arm of a top-level `if` is the root while it shows.

### Who wins?   {#precedence}

The caller. The value is written after the component's own on that element, and an inline value beats a variant's
class — so a `Badge` whose own recipe sets a width takes `w:` from the call.

### Naming one — `label:`   {#label}

A component used twice on one screen needs two names, and it cannot know them — so the caller gives it one. `label:`
lands on the root as its accessible name (`aria-label`), which is also what `Assert.Visible(…, within: "…")` scopes
to in a test. It REPLACES a name the component gives its root itself; an element has one name.

```osy title="two panels, each named by the page" test app=ui-component-root-style-label
[Composable]
component Panel(string title) {
  render { Stack(gap: 2, p: 3, label: title) { Text(title, fontWeight: FontWeight.Medium); Slot; } }
}

[Route("/lines")] [AllowAnonymous]
component LinesPage() {
  render {
    Row(gap: 3) {
      Panel("Open", label: "Open on next") { Text("4 slices"); }
      Panel("Open", label: "Open on maint-4.2") { Text("1 slice"); }
    }
  }
}
```

A component that declares a `label` parameter itself — the kit's `Badge` does — receives the argument instead, as
below.

### What is refused?   {#refused}

- **A prop that paints** — `bg`, `color`, `border`, `fontSize`, `rounded`, `shadow`, … A component's look is its
  own vocabulary (`Badge(…, tone: Tone.Success)`), so twenty screens cannot drift apart; to paint around it, wrap it
  in a `Box` and style the `Box`. The refusal names the component's own parameters.
- **A component with no one root element** — two elements side by side at its top level, a `foreach` (one root per
  row), the caller's own content (`Slot`) or a foreign control. The refusal says which, and writes the wrap.

```osy title="painting is the component's own" syntax
Badge("Late", bg: Colors.Danger);              // ✗ bg PAINTS — use Badge's own vocabulary:
Badge("Late", tone: Tone.Danger);              // ✓
Box(bg: Colors.Muted, p: 2) { Badge("Late"); } // ✓ or paint a wrapper around it
```

### What if the component has a parameter with that name?   {#parameter}

Then it is that parameter, as a named argument is in C#: `Chart(rows, h: 240)` passes `240` to a `Chart` that declares
`int h`, and the chart uses it where it chooses. Only a name the component does not declare is a placement prop.

### Why not a wrapper `Box`?   {#why}

A wrapper is an extra element, and it changes layout by being there: in a `Row`, the flex item is now the `Box`,
not the control, so `grow:` and `alignSelf:` on the control inside it no longer mean anything. Written on the call,
they land on the element the parent actually lays out.

## See also       {#see-also}

- [style props](https://osysharp.com/reference/ui/styling/) — every style prop and the values it takes
- [component](https://osysharp.com/reference/ui/component/) — declaring a component, its parameters and `[Composable]`
- [animationKey — play an animation again when a value changes; a line that draws itself](https://osysharp.com/reference/ui/animation-key/) — replaying an animation when a value changes
