feat(client): phantom-piece palette component

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
claude (blind_chess)
2026-05-18 20:41:43 -04:00
parent c65db03cfa
commit 816f89be36
@@ -0,0 +1,50 @@
<script lang="ts">
import type { Color, PieceType } from '@blind-chess/shared';
import { pieceGlyph } from './pieces.js';
import { phantomDrag } from './stores/phantom-drag.svelte.js';
interface Props { oppColor: Color; }
let { oppColor }: Props = $props();
const TYPES: PieceType[] = ['q', 'r', 'b', 'n', 'p', 'k'];
</script>
<div class="palette">
<span class="hint muted">Drag onto your board — your guess of where the opponent is.</span>
<div class="pieces">
{#each TYPES as t (t)}
<!-- Pointer-only drag source — same deliberate a11y trade-off as the
phantom spans in Board.svelte (no keyboard drag interaction). -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<span
class="pp pp-{oppColor}"
onpointerdown={(e) => { e.preventDefault(); phantomDrag.start({ kind: 'palette', type: t }, e); }}
>{pieceGlyph({ color: oppColor, type: t })}</span>
{/each}
</div>
</div>
<style>
.palette {
display: flex;
flex-direction: column;
gap: 4px;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 8px;
padding: 8px 12px;
}
.hint { font-size: 12px; }
.pieces { display: flex; gap: 6px; }
.pp {
font-size: 30px;
line-height: 1;
cursor: grab;
touch-action: none;
opacity: 0.75;
user-select: none;
}
.pp:hover { opacity: 1; }
.pp-w { color: #fafafa; }
.pp-b { color: #1a1a1a; }
</style>