summaryrefslogtreecommitdiffhomepage
path: root/src/features/layout/ui/TileLeaf.svelte
blob: 0fd643030edbe7d91983cbb1f696f7c59b98b3e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<script lang="ts">
  /**
   * Mounts a registered view for a leaf node. Resolution goes through the
   * REACTIVE registry, so a late registration (plan 03) swaps the tile in
   * without a tree change. An unknown view id renders a fallback tile —
   * NEVER a crash (backend-owned trees can name views this client lacks).
   *
   * A diagnostic `marker` on the leaf draws an outline around it — the only
   * node kind without a natural tile wrapper, so the wrapper exists only
   * when marked (unmarked leaves render exactly as before).
   */
  import type { TileMarker } from "@dispatch/layout-contract";
  import { viewRegistry, type RegisteredView } from "../logic/registry";
  import { MARKER_OUTLINE_OFFSET, markerOutline } from "../logic/marker";
  import FallbackTile from "./FallbackTile.svelte";

  let {
    node,
    ports,
  }: {
    node: { readonly view: string; readonly marker?: TileMarker };
    ports?: unknown;
  } = $props();

  const entry: RegisteredView | undefined = $derived(
    $viewRegistry.find((v) => v.id === node.view),
  );
  const View = $derived(entry?.component);
  const outline = $derived(markerOutline(node.marker));
</script>

{#snippet content()}
  {#if View}
    <View {ports} />
  {:else}
    <FallbackTile viewId={node.view} />
  {/if}
{/snippet}

{#if outline !== undefined}
  <div style:outline={outline} style:outline-offset={MARKER_OUTLINE_OFFSET}>{@render content()}</div>
{:else}
  {@render content()}
{/if}