feat(goal): Focus HUD 목표 가독성·Flash 상기·완료 액션 추가

This commit is contained in:
2026-03-04 15:49:42 +09:00
parent 96b6c0cb8f
commit b38455bf56
3 changed files with 139 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
'use client';
import { cn } from '@/shared/lib/cn';
import { useToast } from '@/shared/ui';
import {
RECOVERY_30S_MODE_LABEL,
Restart30sAction,
@@ -12,6 +13,7 @@ interface SpaceTimerHudWidgetProps {
goal: string;
className?: string;
isImmersionMode?: boolean;
onPlaybackStateChange?: (state: 'running' | 'paused') => void;
}
const HUD_ACTIONS = [
@@ -25,8 +27,11 @@ export const SpaceTimerHudWidget = ({
goal,
className,
isImmersionMode = false,
onPlaybackStateChange,
}: SpaceTimerHudWidgetProps) => {
const { pushToast } = useToast();
const { isBreatheMode, hintMessage, triggerRestart } = useRestart30s();
const normalizedGoal = goal.trim().length > 0 ? goal.trim() : '이번 한 조각을 설정해 주세요.';
return (
<div
@@ -43,7 +48,7 @@ export const SpaceTimerHudWidget = ({
/>
<section
className={cn(
'relative z-10 flex h-16 items-center justify-between gap-3 rounded-2xl px-3.5 transition-colors',
'relative z-10 flex min-h-[4.65rem] items-center justify-between gap-3 rounded-2xl px-3.5 py-2 transition-colors',
isImmersionMode
? 'border border-white/12 bg-black/22 backdrop-blur-md'
: 'border border-white/12 bg-black/24 backdrop-blur-md',
@@ -71,15 +76,30 @@ export const SpaceTimerHudWidget = ({
{timerLabel}
</span>
</div>
<div className="mt-1.5 min-w-0 rounded-lg border border-white/10 bg-black/16 px-2.5 py-1.5">
<div className="flex items-center justify-between gap-2">
<p className="text-[10px] font-medium uppercase tracking-[0.12em] text-white/55">Goal</p>
<button
type="button"
onClick={() => {
pushToast({ title: '완료(더미) — 다음 조각으로 갈까요?' });
}}
className="inline-flex h-5 w-5 items-center justify-center rounded-full border border-white/16 bg-white/[0.05] text-[10px] text-white/78 transition-colors hover:bg-white/[0.12]"
aria-label="목표 완료"
title="목표 완료"
>
</button>
</div>
<p className={cn('mt-0.5 truncate text-sm', isImmersionMode ? 'text-white/90' : 'text-white/88')}>
{normalizedGoal}
</p>
</div>
{hintMessage ? (
<p className={cn('truncate text-[11px]', isImmersionMode ? 'text-white/50' : 'text-white/50')}>
<p className={cn('mt-1 truncate text-[10px]', isImmersionMode ? 'text-white/52' : 'text-white/52')}>
{hintMessage}
</p>
) : (
<p className={cn('truncate text-[11px]', isImmersionMode ? 'text-white/65' : 'text-white/65')}>
: {goal}
</p>
)}
) : null}
</div>
<div className="flex items-center gap-2.5">
@@ -89,6 +109,15 @@ export const SpaceTimerHudWidget = ({
key={action.id}
type="button"
title={action.label}
onClick={() => {
if (action.id === 'start') {
onPlaybackStateChange?.('running');
}
if (action.id === 'pause') {
onPlaybackStateChange?.('paused');
}
}}
className={cn(
'inline-flex h-8 w-8 items-center justify-center rounded-full border text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-200/80',
isImmersionMode