# JoinColumn

Import it from `@grafloria/element`.

Join guidance — live "which column should I join to?" scoring + tinting for
kit table cards, the feature a visual query builder is actually about.

Ported verbatim from a production BI tool's Query Studio (the scoring is ~55
pure lines there too). While a connection drag is in progress, every column
on every OTHER table is scored against the drag's source column and its card
row is tinted by tier:

score 3 — PK↔FK naming convention: `orders.customer_id` ↔ `customers.id`
            (`<singular(table)>_id` on one end, `id` on the other), or exact
            FK column-name equality across tables;
  score 2 — a PK flag on one end and an FK flag on the other;
  score 1 — same column name, or both names end in "id";
  score 0 — same table, or nothing.

Tiers: the single best candidate scoring >= 2 is `top` (gold, "★ BEST"),
every other >= 2 is `good` (green), 1 is `ok` (blue), 0 is `none` (dimmed). The SOURCE table is never tinted, and every tint clears when the drag ends —
complete, cancelled or escaped.

Split the same way the rest of the kit is:
  - `scoreMatch` / `matchTier` / `assignTiers` / `singularize` are PURE
    (unit-specced in the element suite);
  - `bindJoinGuidance(api)` is the runtime: it listens to the engine's own
    connection lifecycle events (`connection:start` / `:complete` /
    `:cancel`) and paints tier classes onto the kit's `.axk-row` elements.

Row tints go on as DOM classes — the renderer's foreignObject subtrees are
patch-opaque, so classes survive the per-frame VNode patch. Port tints go in
as a generated per-drag <style> element keyed by `data-port-id`: port glyphs
ARE re-patched every frame, so a class added to the SVG element would be
wiped mid-drag, while a stylesheet wins the cascade and survives.

```ts
interface JoinColumn
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` |  |  |
| `pk?` | `boolean` |  |  |
| `fk?` | `boolean` |  |  |
