<script lang="ts" generics="T">
  import type { Snippet } from 'svelte';

  let {
    items,
    getKey,
    item
  }: {
    items: T[];
    getKey: (it: T) => string;
    item: Snippet<[T]>;
  } = $props();

  // Compute the divider letter for each item; if it differs from the
  // previous item's letter, that index gets a divider above it.
  const segments = $derived.by(() => {
    const out: { divider: string | null; item: T }[] = [];
    let last: string | null = null;
    for (const it of items) {
      const k = (getKey(it) || '').charAt(0).toUpperCase();
      if (k !== last) {
        out.push({ divider: k, item: it });
        last = k;
      } else {
        out.push({ divider: null, item: it });
      }
    }
    return out;
  });
</script>

<div class="alpha-grid">
  {#each segments as seg, i (i)}
    {#if seg.divider}
      <div class="divider">
        <span class="letter">{seg.divider}</span>
        <span class="rule"></span>
      </div>
    {/if}
    <div class="cell">
      {@render item(seg.item)}
    </div>
  {/each}
</div>

<style>
  .alpha-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 16px;
  }
  .divider {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 12px;
    padding-top: 8px;
  }
  .letter {
    font-family: var(--fs-font-display);
    font-size: 24px;
    font-weight: 500;
    color: var(--fs-parchment);
  }
  .rule {
    flex: 1;
    height: 1px;
    background: var(--fs-pewter);
  }
</style>
