11import { useHabitContext } from "@/components/habit/context"
2+ import { useOrderingContext } from "@/components/ordering/context"
23import { TagContext } from "@/components/tag/context"
34import { useStoredDisplayOptions } from "@/lib/displayOptions"
45import { cn } from "@/lib/utils"
56import type { Habit } from "@/proto/models/v1/models_pb"
7+ import { useSortable } from "@dnd-kit/sortable"
8+ import { CSS } from "@dnd-kit/utilities"
69import { Link } from "@tanstack/react-router"
710import React from "react"
811
@@ -20,18 +23,54 @@ const matchActiveTags = (h: Habit, active?: Set<string>): boolean => {
2023 return false
2124}
2225
26+ const LinkWrapper : React . FC < React . PropsWithChildren > = ( { children } ) => {
27+ const { isReordering } = useOrderingContext ( )
28+ const { habit } = useHabitContext ( )
29+
30+ if ( isReordering ) {
31+ return children
32+ }
33+
34+ return (
35+ < Link
36+ to = "/habits/$name"
37+ params = { { name : habit . name } }
38+ className = "flex flex-col justify-center grow h-full min-h-11"
39+ >
40+ { children }
41+ </ Link >
42+ )
43+ }
44+
2345export const HabitCard : React . FC = ( ) => {
2446 const tags = React . useContext ( TagContext )
2547 const { habit, color, isCompleted } = useHabitContext ( )
48+ const { isReordering } = useOrderingContext ( )
49+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable ( {
50+ id : habit . name ,
51+ } )
52+ const style : React . CSSProperties = {
53+ transform : CSS . Transform . toString ( transform ) ,
54+ transition,
55+ }
2656 const [ displayOptions ] = useStoredDisplayOptions ( )
2757
2858 if ( ! matchActiveTags ( habit , tags . active ) ) return null
2959
60+ const extraProps = isReordering
61+ ? { ref : setNodeRef , style, ...attributes , ...listeners }
62+ : undefined
63+
3064 return (
3165 < div
32- className = { cn ( "habit-card rounded truncate w-full max-w-211 flex flex-col gap-1" , {
33- "min-h-40" : ! displayOptions . hideChart ,
34- } ) }
66+ { ...extraProps }
67+ className = { cn (
68+ "habit-card rounded truncate w-full max-w-211 flex flex-col gap-1" ,
69+ {
70+ "min-h-40" : ! displayOptions . hideChart ,
71+ } ,
72+ { "cursor-move" : isReordering } ,
73+ ) }
3574 >
3675 < div
3776 className = { cn (
@@ -41,22 +80,18 @@ export const HabitCard: React.FC = () => {
4180 color . lightBackground ,
4281 { "pt-1" : ! displayOptions . hideProgressbar } ,
4382 { "py-1" : displayOptions . hideProgressbar } ,
44- { "opacity-50" : isCompleted } ,
83+ { "opacity-50" : isCompleted && ! isReordering } ,
4584 ) }
4685 >
4786 < div className = { cn ( "flex items-center gap-1 w-full px-2 pl-3 min-h-11" ) } >
48- < Link
49- to = "/habits/$name"
50- params = { { name : habit . name } }
51- className = "flex flex-col justify-center grow h-full min-h-11"
52- >
87+ < LinkWrapper >
5388 < div className = "flex items-center gap-3 grow" >
5489 < HabitIcon size = { 20 } className = "w-6" />
5590
5691 < div className = "flex flex-col gap-0" >
5792 < span
5893 className = { cn ( "max-w-120 overflow-hidden text-ellipsis" , {
59- "line-through" : isCompleted ,
94+ "line-through" : isCompleted && ! isReordering ,
6095 } ) }
6196 title = { habit . name }
6297 >
@@ -73,11 +108,13 @@ export const HabitCard: React.FC = () => {
73108 ) }
74109 </ div >
75110 </ div >
76- </ Link >
111+ </ LinkWrapper >
77112
78- < div className = "ml-auto flex items-center gap-1 overflow-hidden" >
79- < CompletionButtons max = { 2 } />
80- </ div >
113+ { ! isReordering && (
114+ < div className = "ml-auto flex items-center gap-1 overflow-hidden" >
115+ < CompletionButtons max = { 2 } />
116+ </ div >
117+ ) }
81118 </ div >
82119
83120 { ! displayOptions . hideProgressbar && < HabitProgress /> }
0 commit comments