Fix production class extraction by replacing template-literal classNames with cn()
All checks were successful
CI / check (push) Successful in 1m22s
CI / build-image (push) Successful in 29s

Tailwind v4's static extractor missed classes adjacent to ${} in template
literals (e.g. `pb-8${...}`), causing missing styles in production builds.
Migrated all dynamic classNames to cn() and added a check script to prevent
regressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-16 12:56:15 +01:00
parent 6e10238fe0
commit 8aec460ee4
6 changed files with 88 additions and 23 deletions

View File

@@ -30,6 +30,7 @@ import { useBulkImport } from "./hooks/use-bulk-import";
import { useEncounter } from "./hooks/use-encounter";
import { usePlayerCharacters } from "./hooks/use-player-characters";
import { useSidePanelState } from "./hooks/use-side-panel-state";
import { cn } from "./lib/utils";
function rollDice(): number {
return Math.floor(Math.random() * 20) + 1;
@@ -53,12 +54,12 @@ function useActionBarAnimation(combatantCount: number) {
}, [combatantCount]);
const empty = combatantCount === 0;
const risingClass = rising ? " animate-rise-to-center" : "";
const settlingClass = settling ? " animate-settle-to-bottom" : "";
const risingClass = rising ? "animate-rise-to-center" : "";
const settlingClass = settling ? "animate-settle-to-bottom" : "";
const exitingClass = topBarExiting
? " absolute inset-x-0 top-0 z-10 px-4 animate-slide-up-out"
? "absolute inset-x-0 top-0 z-10 px-4 animate-slide-up-out"
: "";
const topBarClass = settling ? " animate-slide-down-in" : exitingClass;
const topBarClass = settling ? "animate-slide-down-in" : exitingClass;
const showTopBar = !empty || topBarExiting;
return {
@@ -200,7 +201,7 @@ export function App() {
<div className="relative mx-auto flex min-h-0 w-full max-w-2xl flex-1 flex-col gap-3 px-4">
{!!actionBarAnim.showTopBar && (
<div
className={`shrink-0 pt-8${actionBarAnim.topBarClass}`}
className={cn("shrink-0 pt-8", actionBarAnim.topBarClass)}
onAnimationEnd={actionBarAnim.onTopBarExitEnd}
>
<TurnNavigation
@@ -216,7 +217,7 @@ export function App() {
/* Empty state — ActionBar centered */
<div className="flex min-h-0 flex-1 items-center justify-center pt-8 pb-[15%]">
<div
className={`w-full${actionBarAnim.risingClass}`}
className={cn("w-full", actionBarAnim.risingClass)}
onAnimationEnd={actionBarAnim.onRiseEnd}
>
<ActionBar
@@ -275,7 +276,7 @@ export function App() {
{/* Action Bar — fixed at bottom */}
<div
className={`shrink-0 pb-8${actionBarAnim.settlingClass}`}
className={cn("shrink-0 pb-8", actionBarAnim.settlingClass)}
onAnimationEnd={actionBarAnim.onSettleEnd}
>
<ActionBar