Files
ttrpg_manager/src/components/ui/RollTray.tsx
T
NilsBriggen 522ff8abce Phase 6: character creation & level-up
- Ability generation: standard array, point buy (27-pt, validated), 4d6kh3 roll;
  AbilityGenModal with assign-from-pool + steppers (pure abilityGen lib + tests)
- Level-up flow: increment level, HP gain (average or roll hit die + CON)
- Print / save-to-PDF: print button + @media print hides app chrome and roll tray
- Plan: added Phase 11 (data-driven Assistant) to the roadmap

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 01:56:23 +02:00

35 lines
1.4 KiB
TypeScript

import { useRollStore } from '@/stores/rollStore';
import { DEGREE_COLOR, DEGREE_LABEL } from '@/lib/dice/check';
import { cn } from '@/lib/cn';
/** Floating result of the most recent roll, shared across the whole app. */
export function RollTray() {
const last = useRollStore((s) => s.last);
const dismiss = useRollStore((s) => s.dismiss);
if (!last) return null;
return (
<div data-roll-tray className="pointer-events-none fixed bottom-4 right-4 z-50 w-72 print:hidden">
<div
key={last.seq}
className="animate-dice-settle pointer-events-auto rounded-lg border border-line bg-panel p-4 shadow-2xl"
>
<div className="flex items-start justify-between gap-2">
<div className="min-w-0">
{last.label && <div className="truncate text-xs font-medium text-muted">{last.label}</div>}
{last.degree && (
<div className={cn('text-xs font-semibold', DEGREE_COLOR[last.degree])}>
{DEGREE_LABEL[last.degree]}
{last.dc !== undefined ? ` (DC ${last.dc})` : ''}
</div>
)}
</div>
<button onClick={dismiss} aria-label="Dismiss roll" className="text-muted hover:text-ink"></button>
</div>
<div className="mt-1 font-display text-4xl font-bold text-accent">{last.result.total}</div>
<div className="mt-1 font-mono text-xs text-muted">{last.result.breakdown}</div>
</div>
</div>
);
}