Skip to content

Commit 6d1467d

Browse files
author
nedtwigg
committed
Claude Code simplify: extract shared bellIconClass helper, deduplicate hover class, update spec for tilt-based visuals
1 parent e0dcfb6 commit 6d1467d

4 files changed

Lines changed: 33 additions & 44 deletions

File tree

docs/specs/alarm.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,13 @@ Alarm button:
248248
- icon-only control with tooltip and accessible label
249249
- visual states (pure function of `status`):
250250
- `ALARM_DISABLED`: `BellSlashIcon`, muted
251-
- `NOTHING_TO_SHOW`: `BellIcon` filled, muted
252-
- `MIGHT_BE_BUSY`: `BellIcon` filled, muted, with a faint dot badge (`foreground/40`, static)
253-
- `BUSY`: `BellIcon` filled, muted, with an accent-colored dot badge (gentle breathing pulse)
254-
- `MIGHT_NEED_ATTENTION`: `BellIcon` filled, muted, with a warning-colored dot badge (`warning/60`, gentle breathing pulse)
255-
- `ALARM_RINGING`: `BellIcon` filled, warning color, whole-button breathing pulse; no dot badge
256-
- the dot badge is a small circle positioned at the top-right corner of the bell icon
257-
- the dot badge has a `border-surface-alt` outline to cleanly separate it from the bell icon
258-
- the dot badge must not change the button's layout size
251+
- `NOTHING_TO_SHOW`: `BellIcon` filled, muted, upright
252+
- `MIGHT_BE_BUSY`: `BellIcon` filled, muted, tilted slightly (-22.5°)
253+
- `BUSY`: `BellIcon` filled, muted, tilted 45°
254+
- `MIGHT_NEED_ATTENTION`: `BellIcon` filled, muted, tilted 60°
255+
- `ALARM_RINGING`: `BellIcon` filled, warning color, rocking animation (±45° bell-ring keyframe); reduced-motion: static 45° tilt
256+
- escalation is conveyed by increasing tilt angle, not by a separate badge element
257+
- the tilt/animation must not change the button's layout size
259258

260259
Interaction (`dismissOrToggleAlarm` state machine):
261260

@@ -281,8 +280,8 @@ Door indicators:
281280

282281
- show bell indicator only when `status !== 'ALARM_DISABLED'`
283282
- show TODO pill when `hasTodo(todo)` (soft or hard)
284-
- if `status === 'ALARM_RINGING'`, the Door itself gets the ringing treatment, not just a tiny icon
285-
- the Door bell icon shows the same dot badge as the Pane header for `MIGHT_BE_BUSY`, `BUSY`, and `MIGHT_NEED_ATTENTION` states, but smaller (4px vs 6px) to match the smaller bell icon
283+
- if `status === 'ALARM_RINGING'`, the Door bell icon uses warning color and the same rocking animation as the Pane header
284+
- the Door bell icon shows the same tilt angles as the Pane header for escalation states
286285

287286
Door interaction:
288287

lib/src/components/Door.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BellIcon } from '@phosphor-icons/react';
22
import { TODO_OFF, isSoftTodo, type SessionStatus, type TodoState } from '../lib/terminal-registry';
33
import { useTodoPillContent } from './TodoPillBody';
4-
import { cfg } from '../cfg';
4+
import { bellIconClass } from './bell-icon-class';
55

66
export interface DoorProps {
77
doorId?: string;
@@ -66,21 +66,7 @@ export function Door({
6666
)}
6767
{alarmEnabled && (
6868
<span className={[alarmRinging ? 'text-warning' : (isActive && windowFocused) ? 'text-foreground' : 'text-muted'].join(' ')}>
69-
<BellIcon
70-
size={11}
71-
weight="fill"
72-
className={[
73-
'transition-transform',
74-
status === 'MIGHT_BE_BUSY' && '-rotate-[22.5deg]',
75-
status === 'BUSY' && 'rotate-45',
76-
status === 'MIGHT_NEED_ATTENTION' && 'rotate-[60deg]',
77-
status === 'ALARM_RINGING' && (
78-
cfg.alarm.ringingPaused
79-
? 'rotate-45'
80-
: 'motion-safe:animate-bell-ring motion-reduce:rotate-45'
81-
),
82-
].filter(Boolean).join(' ')}
83-
/>
69+
<BellIcon size={11} weight="fill" className={bellIconClass(status)} />
8470
</span>
8571
)}
8672
</span>

lib/src/components/Pond.tsx

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { getPlatform } from '../lib/platform';
5858
import { saveSession } from '../lib/session-save';
5959
import type { PersistedDetachedItem } from '../lib/session-types';
6060
import { cfg } from '../cfg';
61+
import { bellIconClass } from './bell-icon-class';
6162
import { useTodoPillContent } from './TodoPillBody';
6263

6364
// --- Theme ---
@@ -700,10 +701,10 @@ export function TerminalPaneHeader({ api }: IDockviewPanelHeaderProps) {
700701
)}
701702
<HeaderActionButton
702703
className={[
703-
'flex h-5 min-w-5 items-center justify-center rounded transition-colors shrink-0',
704+
'flex h-5 min-w-5 items-center justify-center rounded transition-colors shrink-0 hover:bg-foreground/10',
704705
sessionState.status === 'ALARM_RINGING'
705-
? 'text-warning hover:bg-foreground/10'
706-
: 'text-muted hover:bg-foreground/10 hover:text-foreground',
706+
? 'text-warning'
707+
: 'text-muted hover:text-foreground',
707708
].join(' ')}
708709
onMouseDownCapture={(e) => {
709710
if (e.button !== 0) return;
@@ -729,21 +730,7 @@ export function TerminalPaneHeader({ api }: IDockviewPanelHeaderProps) {
729730
{sessionState.status === 'ALARM_DISABLED' ? (
730731
<BellSlashIcon size={14} />
731732
) : (
732-
<BellIcon
733-
size={14}
734-
weight="fill"
735-
className={[
736-
'transition-transform',
737-
sessionState.status === 'MIGHT_BE_BUSY' && '-rotate-[22.5deg]',
738-
sessionState.status === 'BUSY' && 'rotate-45',
739-
sessionState.status === 'MIGHT_NEED_ATTENTION' && 'rotate-[60deg]',
740-
sessionState.status === 'ALARM_RINGING' && (
741-
cfg.alarm.ringingPaused
742-
? 'rotate-45'
743-
: 'motion-safe:animate-bell-ring motion-reduce:rotate-45'
744-
),
745-
].filter(Boolean).join(' ')}
746-
/>
733+
<BellIcon size={14} weight="fill" className={bellIconClass(sessionState.status)} />
747734
)}
748735
</span>
749736
</HeaderActionButton>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { cfg } from '../cfg';
2+
import type { SessionStatus } from '../lib/terminal-registry';
3+
4+
/** Returns the Tailwind className string for a BellIcon's rotation/animation based on alarm status. */
5+
export function bellIconClass(status: SessionStatus): string {
6+
return [
7+
'transition-transform',
8+
status === 'MIGHT_BE_BUSY' && '-rotate-[22.5deg]',
9+
status === 'BUSY' && 'rotate-45',
10+
status === 'MIGHT_NEED_ATTENTION' && 'rotate-[60deg]',
11+
status === 'ALARM_RINGING' && (
12+
cfg.alarm.ringingPaused
13+
? 'rotate-45'
14+
: 'motion-safe:animate-bell-ring motion-reduce:rotate-45'
15+
),
16+
].filter(Boolean).join(' ');
17+
}

0 commit comments

Comments
 (0)