Various UX improvements.

This commit is contained in:
Greyson Parrelli
2026-07-24 07:54:58 -04:00
parent dd395f4bbf
commit 962e3bb5ff
5 changed files with 223 additions and 13 deletions
+46 -6
View File
@@ -32,8 +32,8 @@ function useFitText(dep: unknown) {
// renderEffect bolds each effect's trigger and renders the colon separating it
// from the action as an arrow, so "Sell: add 1 extra Apple" shows "Sell →" in
// bold. Cards can list several effects joined by " · "; each gets its own
// bolded trigger.
// bold. Cards can list several effects joined by " · "; each is stacked on its
// own line rather than run together.
function renderEffect(text: string) {
return text.split(' · ').map((segment, i) => {
const colon = segment.indexOf(':')
@@ -47,14 +47,41 @@ function renderEffect(text: string) {
</>
)
return (
<span key={i}>
{i > 0 && ' · '}
<span className="card-effect-line" key={i}>
{node}
</span>
)
})
}
// TRIGGER_GLOSS explains when each ability fires, shown under the hover
// magnifier so the trigger words aren't jargon.
const TRIGGER_GLOSS: Record<string, string> = {
Faint: 'when this pet is knocked out',
Play: 'when it enters the battle',
Hurt: 'when it survives taking damage',
Sell: 'when you sell it in the shop',
Buy: 'when you buy it',
Triple: 'when traded in as one of three',
'After Attacking': 'right after it attacks in a clash',
'Battle Prep': 'as the battle is arranged',
'Shop start': 'when the shop opens each round',
'Enemy Faints': 'when an enemy pet is knocked out',
'Enemy Played': 'when the enemy plays a pet',
}
// triggersOf extracts the trigger words (the part before each ":") from an
// effect string.
function triggersOf(text?: string): string[] {
if (!text) return []
const out: string[] = []
for (const seg of text.split(' · ')) {
const colon = seg.indexOf(':')
if (colon > 0) out.push(seg.slice(0, colon).trim())
}
return out
}
interface Props {
card: Card
size?: 'sm' | 'md' | 'lg'
@@ -113,11 +140,24 @@ export function CardView({
<div
className="card-magnify"
style={{
left: Math.min(hover.x + 24, window.innerWidth - 180),
top: Math.min(Math.max(hover.y - 120, 8), window.innerHeight - 250),
left: Math.min(hover.x + 24, window.innerWidth - 200),
top: Math.min(Math.max(hover.y - 120, 8), window.innerHeight - 320),
}}
>
<CardView card={card} size="lg" bonus={bonus} damage={damage} dead={dead} preview />
{(() => {
const trigs = triggersOf(card.effectText).filter((t) => TRIGGER_GLOSS[t])
if (trigs.length === 0) return null
return (
<div className="trigger-gloss">
{trigs.map((t) => (
<div className="trigger-gloss-line" key={t}>
<strong>{t}</strong> {TRIGGER_GLOSS[t]}
</div>
))}
</div>
)
})()}
</div>,
document.body,
)