# `PartState.outline`

> Contract 2.0.0 · package sha256 `a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e` · generated from `configurator-runtime.d.ts` by `services/onsite-scripter/scripts/build-contract-docs.mjs`; edit the source, not this file.

Property of [`PartState`](PartState.md) · stable · since 2.0.0

```ts
outline?: {
  color: ColorValue;
  widthPx?: number;
} | null;
```

A screen-space outline around the parts, for hover and selection. To outline the product as a
whole, as 1.x's highlight did (it resolved the hovered mesh to its model root), write it from
your `'hover'` handler on the hovered part's model root ([`node(hit.part.node)`](Writer.node.md)), or for a
collection part on its collection's `root` (or its item, `part(key)`, when each item is a
product), and only when that changes: 'hover' fires whenever the part under the pointer
changes, and each outline write is a look commit (a feed entry and a 'committed' event).
Null when the hover ends; the same write on the selected product. Look only: the
parts keep their colour, and it is never saved or exported; a capture includes it. It follows
skinned and animated parts and holds across a level-of-detail swap. It is never drawn into
the shadow map or the ambient-occlusion pass, and never counts for picking or bounds.
It is cleared when its part leaves the scene (a scene write removes or disables its model, or
its item is removed), so it doesn't come back with it.
On a group part it outlines every mesh below. Reset it with null.

**Default:** unchanged

## Example

Imports: values (`has`, `validate`, the `Holo*Error` classes, the pure helpers) from `@holostep-configurators/runtime-client`, types from `@holostep-configurators/runtime-client/contract`, `/math` and `/testing` names from those entries; `boot` from the runtime module the root's `loadRuntimeAtFloor` resolves to. A type your page defines is your app's: declare it there, never import it from the package.

Compiled under the contract's strict settings (`examples/declaration/06-PartState.outline.ts`):

```ts
import type { CommitOptions, Part, Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
const look = { color: '#2f80ed', widthPx: 2 } as const;
// The product a part belongs to: its model's root, else its collection's root.
const productOf = (p: Part<CommitOptions>): Part<CommitOptions> =>
  p.node !== null ? session.node(p.node)
    : p.collection !== null ? session.collection(p.collection).root : p;
let hovered: Part<CommitOptions> | null = null;
let hoveredId: string | null = null;
session.on('hover', ({ hit }) => {
  const next = hit ? productOf(hit.part) : null;
  const id = next ? `${next.node ?? next.collection}/${next.id}` : null;
  if (id === hoveredId) return;                    // 'hover' fires per part: write per product
  void hovered?.set({ outline: null });
  hovered = next;
  hoveredId = id;
  void hovered?.set({ outline: look });
}, { signal });
// A selection outline is the same write on the selected product, reset with null when the
// selection moves; a model that leaves the scene takes its outline with it.
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `outline` names no product |
| 2. A precedent | pass: [Babylon.js HighlightLayer](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Layers/highlightLayer.ts) (row `G38`); [Babylon.js OutlineRenderer](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Rendering/outlineRenderer.ts) (row `G38`); [Unity LineRenderer](https://docs.unity3d.com/ScriptReference/LineRenderer.html) (row `K49`); [Babylon.js EdgesRenderer](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Rendering/edgesRenderer.ts) (row `K49`) |
| 3. Two apps, or labs | pass: 9 apps (ledger: app-378d190f1b, app-4f16d2f6da, app-510d750508, app-822bb9d6aa, app-b4ae2fce25, app-ceb4eccc72, app-ddfb017681, app-fc07850558 and 1 more; fleet cross-check: app-4f16d2f6da, app-510d750508, app-822bb9d6aa, app-ceb4eccc72) |
| 4. The cheaper fix first | decided per need in Appendix B: rows `G38`, `K49` at tier stable (a member only where no rule, data, asset or app code serves the need) |
