<!-- 04_VISUAL/xwui/xwui-lib/xwui-lib-super/src/forms/XWUIFieldMapper/XWUIFieldMapper.md -->
# XWUIFieldMapper

Maps a source list to a target list: file columns to plnx fields, a remote tool's fields to plnx columns, status values to
status pills, remote people to plnx people. Every row carries a state (matched, suggested with a confidence and a visible
reason, accepted, skipped, external, type mismatch, not supported, approximated, needs attention); a person accepts or rejects
each suggestion, or all of them at once; two rows on one target are flagged; Reset returns every row to its suggested
default; a row can carry a transform; a test runs the sample records through the mapping and previews them. It draws as a
real table, as labelled groups on narrow hosts, or as two columns joined by measured wires. It composes basic `XWUITag`
(state and value pills) and `XWUIAvatar` (people) and, for the wires, super `XWUIBeamLayer`. It never writes anything: every
change is an event the host commits (GUIDE_16 suggest).

## Basic Usage

```example
file: examples/BasicUsage.ts
html: examples/BasicUsage.html
title: Basic Usage
description: CSV import columns: a picker per column, Reset to suggested, a duplicate is flagged.
```

## Connect Fields

```example
file: examples/ConnectFields.ts
html: examples/ConnectFields.html
title: Connect Fields
description: Connect wizard fields: sync direction, suggestions with a visible reason, Accept, Reject and Accept all.
```

## Status Values

```example
file: examples/StatusValues.ts
html: examples/StatusValues.html
title: Status Values
description: Remote status values to coloured plnx status pills; many to one is allowed.
```

## People Match

```example
file: examples/PeopleMatch.ts
html: examples/PeopleMatch.html
title: People Match
description: Remote people matched by email or by name, one person stays external.
```

## Mapping Studio

```example
file: examples/MappingStudio.ts
html: examples/MappingStudio.html
title: Mapping Studio
description: Two columns joined by measured wires, per-row transforms and a test over 5 sample records.
```

## Data

| Field | Shape |
| --- | --- |
| `rows[]` | `{ id, source, sourceMeta?, sourceType?, sample?, target?, state, confidence?, reason?, direction?, transform?, result?, defaultTargetId? }` |
| `targets[]` | `{ id, label, type?, required?, kind?, tone?, avatar? }`: what a picker offers; the wires layout draws them as its second column |
| `transforms[]` | `{ id, label }`: what a transform picker offers |
| `sampleRows[]` | records for a test run, keyed by row id or by source name |
| `status`, `message` | `loading` (skeleton rows), `error` (an alert with `message`), default `ready` |

Row fields: `target` `{ id, label, kind?: 'text' | 'pill' | 'person', tone?, avatar? }` or null; `state` `matched`, `suggested`,
`accepted`, `skipped`, `external`, `mismatch`, `unsupported`, `approx`, `error`; `confidence` 0..100 (shown for `suggested`);
`reason` visible text under the source; `direction` `in`, `out`, `both`, `none`; `result` `{ value, pending? }` (a progressive
count); `defaultTargetId` the suggested target (null: not mapped by default), which Reset restores and against which a row
reads as changed. A `tone` is a role (`neutral`, `primary`, `success`, `warning`, `error`) or a hue name (`teal`, `rose`, ...).

Coverage counts rows that are `matched`, `accepted`, `approx` or `mismatch` with a target; a suggestion counts once accepted.

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `mode` | `'fields'` | `columns`, `fields`, `values`, `people`: the default copy, the coverage noun, how a target draws, what "not mapped" means (people stay external). |
| `layout` | `'auto'` | `auto` a table that stacks below `stackBelow`; `table`; `stack`; `wires` (stacks below `stackBelow`). |
| `editable` | `true` | A target picker per row, and a transform picker when `transforms` exist. |
| `readonly` | `false` | Nothing can change: no pickers, Accept, Reject or toolbar actions. |
| `showDirection` | `false` | A sync direction column. |
| `showCoverage` | `true` | "8 of 10 fields mapped", a polite live region. |
| `acceptAll` | `true` | "Accept all suggestions" while one waits. |
| `confidenceThreshold` | `80` | Under it a suggestion is low (amber with a dashed edge). |
| `detectDuplicates` | by mode | On for `columns` and `fields`, off for `values` and `people`. |
| `sourceDir` | `'ltr'` | `ltr`: source names are identifiers; `auto`: language text. |
| `stackBelow` | `560` | Container width in px below which `auto` and `wires` stack. |
| `showAutoMap` | `false` | "Auto-map": name-based suggestions for unmapped rows (a person still accepts them). |
| `showReset` | `true` | "Reset to suggested" when rows carry `defaultTargetId`. |
| `showTest` | `true` | "Test with N records" when `sampleRows` exist. |
| `testRows` | `5` | Most records a test previews. |
| `ariaLabel`, `labels` | mode title | Every word; `{source}`, `{target}`, `{n}`, `{total}` are filled. |
| `locale`, `numberingSystem` | page, `'latn'` | Number formatting; Western digits by default. |

## Events and methods

Events (logic, and bubbling DOM events on the host): `mappingChange { id, targetId, source }` (`mapping-change`; REF_06 calls it
`change`, a name the base logic already uses for its state signal), `accept { id }` (`mapping-accept`), `reject { id }`
(`mapping-reject`), `acceptAll { ids }` (`mapping-accept-all`), `autoMap { ids }` (`mapping-auto-map`), `reset { ids }`
(`mapping-reset`), `test { rows }` (`mapping-test`, rows are target id to value), `transformChange { id, transform }`
(`mapping-transform-change`). Each user action also updates `data.rows`, so a listening host stays in sync; a host that owns the
rows answers with `setData`.

Methods: `setTarget(id, targetId | null)`, `accept(id)`, `reject(id)`, `acceptAll()`, `autoMap()`, `reset()`, `runTest()`,
`setTransform(id, transformId | null)`, `getCoverage()`, `getLayout()`, `remeasure()`, the `on*` subscriptions, `updateData`,
`updateConfig`, `getElement()`, `destroy()`. `XWUIFieldMapper.projectView(data, config)` composes a still mapper into a parent's
view tree (no beams).

## States

| State | What shows |
| --- | --- |
| empty | "Nothing to map" (`role=status`) |
| loading | skeleton rows, `aria-busy`, "Loading fields" |
| error | `role=alert` with `message` |
| suggestion | spark chip with the percent, the reason under the source, Accept and Reject |
| collision | "Mapped twice" in the row (also on a waiting suggestion that would collide), a red picker edge, a warning line |
| required target unmapped | a warning line; in wires the target shows "Required" |
| changed from default | "Changed" beside the state, a warning line, Reset enabled |
| tested | a preview table of the mapped sample records and "Nothing is written during a test" |
| reduced motion | no skeleton pulse or fades; the beams stand still |

## Accessibility and RTL

A real table on wide hosts (`th scope=col`, the source cell is `th scope=row`), a group per source named by the source when
stacked, two named lists in the wires layout. Every picker is a native select named "Target for {source}"; Accept and Reject
are buttons named "Accept: {source}" and "Reject: {source}" (the visible "Accept" in people mode is part of the name). Reasons
are visible text, never a tooltip. The coverage line is a polite live region. The wires are decoration (`aria-hidden`): the
lists carry the mapping as text. No colour alone: every state is a word, a low confidence also has a dashed edge, a collision
says "Mapped twice". Direction comes from the parent `dir`; identifiers stay left to right (`sourceDir`), language text reads
`dir="auto"`, the arrow mirrors, wire ports follow the inline edges and the beams are re-measured in the mirrored layout.

## Tokens

Colours: `--text-primary`, `--text-secondary`, `--text-tertiary`, `--bg-card`, `--bg-secondary`, `--bg-hover`,
`--border-subtle`, `--border-strong`, `--accent-primary`, `--accent-success`, `--accent-warning`, `--accent-error`; value
pill hues through `--xwui-tag-hue` (`hueVar`). Knobs: `--xwui-field-mapper-picker-inline-size`,
`--xwui-field-mapper-lane-inline-size`. The nine core hue names (`violet`, `cyan`, ...) exist only in xwflow-neon; elsewhere
they fall back to slate, so pass the extended names (`purple`, `sky`, `teal`, `indigo`, `fuchsia`, `rose`, `slate`, `yellow`).

```api
```
