Tidy: store never writes an undefined ghost; plant card toggle is the face, not the card
Build image / build-and-push (push) Successful in 11s
Build image / build-and-push (push) Successful in 11s
Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -49,36 +49,30 @@ export function PlantCard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
role="button"
|
className={cn('panel relative transition-shadow hover:[box-shadow:var(--shadow-md)]', open && 'border-accent-400')}
|
||||||
tabIndex={0}
|
|
||||||
aria-expanded={open}
|
|
||||||
onClick={() => setOpen((v) => !v)}
|
|
||||||
onKeyDown={(e) => {
|
|
||||||
if (e.target === e.currentTarget && (e.key === 'Enter' || e.key === ' ')) {
|
|
||||||
e.preventDefault()
|
|
||||||
setOpen((v) => !v)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className={cn(
|
|
||||||
'panel relative cursor-pointer px-[18px] py-4 transition-shadow hover:[box-shadow:var(--shadow-md)]',
|
|
||||||
open && 'border-accent-400',
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3">
|
{/* The whole face is the toggle; the expanded area below has its own controls. */}
|
||||||
<Monogram color={plant.color} letters={letters} />
|
<button
|
||||||
<span className="flex min-w-0 flex-col gap-px">
|
type="button"
|
||||||
<span className="truncate font-heading text-[16.5px]" title={plant.name}>
|
aria-expanded={open}
|
||||||
{plant.name}
|
onClick={() => setOpen((v) => !v)}
|
||||||
|
className="block w-full cursor-pointer rounded-[inherit] px-[18px] py-4 text-left"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Monogram color={plant.color} letters={letters} />
|
||||||
|
<span className="flex min-w-0 flex-col gap-px">
|
||||||
|
<span className="truncate font-heading text-[16.5px]" title={plant.name}>
|
||||||
|
{plant.name}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs font-semibold text-ink-mute">{sub.join(' · ')}</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs font-semibold text-ink-mute">{sub.join(' · ')}</span>
|
{builtin && <Tag tone="neutral" className="ml-auto flex-none">built-in</Tag>}
|
||||||
</span>
|
</div>
|
||||||
{builtin && <Tag tone="neutral" className="ml-auto flex-none">built-in</Tag>}
|
<div className="mt-2.5 text-[12.5px] text-ink-soft">{lotText}</div>
|
||||||
</div>
|
</button>
|
||||||
<div className="mt-2.5 text-[12.5px] text-ink-soft">{lotText}</div>
|
|
||||||
|
|
||||||
{open && (
|
{open && (
|
||||||
// Stop clicks inside the expanded area from toggling the card.
|
<div className="-mt-1.5 flex flex-col gap-2 px-[18px] pb-4">
|
||||||
<div className="mt-2.5 flex flex-col gap-2" onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>
|
|
||||||
{lots.map((lot) => (
|
{lots.map((lot) => (
|
||||||
<LotCard key={lot.id} lot={lot} onEdit={() => onEditLot(lot)} onDelete={() => onDeleteLot(lot)} />
|
<LotCard key={lot.id} lot={lot} onEdit={() => onEditLot(lot)} onDelete={() => onDeleteLot(lot)} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -101,7 +101,8 @@ export const useEditorStore = create<EditorState>((set) => ({
|
|||||||
...TRANSIENT,
|
...TRANSIENT,
|
||||||
setSel: (sel) => set({ sel }),
|
setSel: (sel) => set({ sel }),
|
||||||
setFocus: (id) => set({ focusId: id }),
|
setFocus: (id) => set({ focusId: id }),
|
||||||
setArmedKind: (kind) => set({ armedKind: kind, ghost: kind ? undefined : null } as Partial<EditorState>),
|
// Disarming drops the ghost too; arming keeps whatever the cursor last set.
|
||||||
|
setArmedKind: (kind) => set((s) => ({ armedKind: kind, ghost: kind ? s.ghost : null })),
|
||||||
setArmedPlant: (plant, lotId = null) => set({ armedPlant: plant, armedLotId: plant ? lotId : null }),
|
setArmedPlant: (plant, lotId = null) => set({ armedPlant: plant, armedLotId: plant ? lotId : null }),
|
||||||
setArmedLotId: (lotId) => set({ armedLotId: lotId }),
|
setArmedLotId: (lotId) => set({ armedLotId: lotId }),
|
||||||
setGhost: (ghost) => set({ ghost }),
|
setGhost: (ghost) => set({ ghost }),
|
||||||
|
|||||||
Reference in New Issue
Block a user