Build image / build-and-push (push) Successful in 17s
Gadfly on #100: - Extracted the tap-to-arm chip (icon + name + armed state) into a shared PlantChip, used by both RecentPlants and SeedTray, so the two quick-pick surfaces can't drift. SeedTray composes it (rounded={false}) with its remove button into one seamless pill. - Named the recent-strip cap: RECENT_PLANTS_MAX = 8, was a bare slice(0, 8). Verified live: recent chips and the tray render identically post-refactor. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01H3zbym8Doka2d7D48maSgZ
58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
import { cn } from '@/lib/cn'
|
|
import { PlantChip } from '@/components/plants/PlantChip'
|
|
import type { Plant } from '@/lib/plants'
|
|
|
|
/**
|
|
* The Seed Tray strip in the focus-mode toolbar: a row of the garden's
|
|
* kept-at-hand plants. Tap a chip to arm that plant for tap-to-place (the armed
|
|
* chip is highlighted); ✕ removes it from the tray; the trailing "+ Plant" chip
|
|
* opens the full catalog picker. See useSeedTray for persistence.
|
|
*/
|
|
export function SeedTray({
|
|
trayPlants,
|
|
armedPlantId,
|
|
onArm,
|
|
onRemove,
|
|
onOpenPicker,
|
|
}: {
|
|
trayPlants: Plant[]
|
|
armedPlantId: number | null
|
|
onArm: (plant: Plant) => void
|
|
onRemove: (id: number) => void
|
|
onOpenPicker: () => void
|
|
}) {
|
|
return (
|
|
<div className="flex flex-wrap items-center gap-1.5">
|
|
{trayPlants.map((p) => {
|
|
const active = p.id === armedPlantId
|
|
return (
|
|
<span key={p.id} className="inline-flex items-center">
|
|
{/* Flat right edge so the remove button below seams into one pill. */}
|
|
<PlantChip plant={p} active={active} onArm={onArm} rounded={false} />
|
|
<button
|
|
type="button"
|
|
onClick={() => onRemove(p.id)}
|
|
aria-label={`Remove ${p.name} from tray`}
|
|
className={cn(
|
|
'rounded-r-full border border-l-0 px-1.5 py-1 text-xs outline-none transition-colors focus-visible:ring-2 focus-visible:ring-accent/40',
|
|
active
|
|
? 'border-accent bg-accent/10 text-accent-strong hover:text-fg'
|
|
: 'border-border bg-surface text-muted hover:text-fg',
|
|
)}
|
|
>
|
|
✕
|
|
</button>
|
|
</span>
|
|
)
|
|
})}
|
|
<button
|
|
type="button"
|
|
onClick={onOpenPicker}
|
|
className="inline-flex items-center gap-1 rounded-full border border-dashed border-border px-2.5 py-1 text-xs font-medium text-muted outline-none transition-colors hover:border-accent hover:text-accent-strong focus-visible:ring-2 focus-visible:ring-accent/40"
|
|
>
|
|
+ Plant
|
|
</button>
|
|
</div>
|
|
)
|
|
}
|