1- import React , { useEffect } from "react" ;
2- import { useListData } from "react-stately" ;
1+ import React from "react" ;
32import {
43 Button ,
54 ListBox ,
@@ -13,6 +12,7 @@ import { cn } from "../../utils";
1312import DragAndDropIcon from "../../assets/svgs/drag-and-drop.svg" ;
1413import Trash from "../../assets/svgs/trash.svg" ;
1514import clsx from "clsx" ;
15+ import { useList } from "./useList" ;
1616
1717type ListItem = {
1818 id : string | number ;
@@ -53,24 +53,26 @@ function DraggableList({
5353 deletionDisabled = false ,
5454 ...props
5555} : Readonly < IDraggableList > ) {
56- const list = useListData ( {
56+ const {
57+ items : list ,
58+ moveAfter,
59+ moveBefore,
60+ remove,
61+ getItem,
62+ } = useList ( {
5763 initialItems : items ,
64+ onChange : updateCallback ,
5865 } ) ;
5966
60- useEffect ( ( ) => {
61- if ( ! updateCallback ) return ;
62- updateCallback ( list . items ) ;
63- } , [ list , updateCallback , items ] ) ;
64-
6567 const { dragAndDropHooks } = useDragAndDrop ( {
6668 getItems : ( keys ) =>
67- [ ...keys ] . map ( ( key ) => ( { "text/plain" : list . getItem ( key ) ! . name } ) ) ,
69+ [ ...keys ] . map ( ( key ) => ( { "text/plain" : getItem ( key ) ! . name } ) ) ,
6870 getAllowedDropOperations : ( ) => [ "move" ] ,
6971 onReorder ( e ) {
7072 if ( e . target . dropPosition === "before" ) {
71- list . moveBefore ( e . target . key , e . keys ) ;
73+ moveBefore ( e . target . key , e . keys ) ;
7274 } else if ( e . target . dropPosition === "after" ) {
73- list . moveAfter ( e . target . key , e . keys ) ;
75+ moveAfter ( e . target . key , e . keys ) ;
7476 }
7577 } ,
7678 renderDragPreview,
@@ -81,11 +83,11 @@ function DraggableList({
8183 { ...props }
8284 aria-label = { props [ "aria-label" ] ?? "Reorderable list" }
8385 selectionMode = "single"
84- items = { list . items }
86+ items = { list }
8587 dragAndDropHooks = { dragDisabled ? undefined : dragAndDropHooks }
8688 onSelectionChange = { ( keys ) => {
8789 const keyArr = Array . from ( keys ) ;
88- const selectedItem = list . getItem ( keyArr [ 0 ] ) ;
90+ const selectedItem = getItem ( keyArr [ 0 ] ) ;
8991
9092 if ( selectionCallback && selectedItem ) selectionCallback ( selectedItem ) ;
9193 } }
@@ -96,50 +98,53 @@ function DraggableList({
9698 className ,
9799 ) }
98100 >
99- { ( item ) => (
100- < ListBoxItem
101- textValue = { item . name }
102- className = { ( { isHovered, isDragging, isSelected } ) =>
103- cn (
104- "h-11.25 w-full cursor-pointer border-l-3 border-l-transparent" ,
105- "flex items-center gap-4 px-4" ,
106- "focus-visible:outline-klerosUIComponentsPrimaryBlue focus-visible:outline" ,
107- ( isHovered || isSelected ) && "bg-klerosUIComponentsMediumBlue" ,
108- isSelected && "border-l-klerosUIComponentsPrimaryBlue" ,
109- isDragging && "cursor-grabbing opacity-60" ,
110- )
111- }
112- >
113- { ( { isHovered } ) => (
114- < >
115- { dragDisabled ? null : (
116- < DragAndDropIcon className = "size-4 cursor-grab" />
117- ) }
118- < span className = "text-klerosUIComponentsPrimaryText flex-1 text-base" >
119- { item . name }
120- </ span >
121- { isHovered && ! deletionDisabled ? (
122- < Button
123- className = { "cursor-pointer hover:scale-105" }
124- onPress = { ( ) => {
125- list . remove ( item . id ) ;
126- } }
127- >
128- { ( { isHovered : isButtonHovered } ) => (
129- < Trash
130- className = { clsx (
131- "ease-ease size-4 transition" ,
132- isButtonHovered &&
133- "[&_path]:fill-klerosUIComponentsPrimaryBlue" ,
134- ) }
135- />
136- ) }
137- </ Button >
138- ) : null }
139- </ >
140- ) }
141- </ ListBoxItem >
142- ) }
101+ { items . map ( ( item ) => {
102+ return (
103+ < ListBoxItem
104+ key = { item . id }
105+ textValue = { item . name }
106+ className = { ( { isHovered, isDragging, isSelected } ) =>
107+ cn (
108+ "h-11.25 w-full cursor-pointer border-l-3 border-l-transparent" ,
109+ "flex items-center gap-4 px-4" ,
110+ "focus-visible:outline-klerosUIComponentsPrimaryBlue focus-visible:outline" ,
111+ ( isHovered || isSelected ) && "bg-klerosUIComponentsMediumBlue" ,
112+ isSelected && "border-l-klerosUIComponentsPrimaryBlue" ,
113+ isDragging && "cursor-grabbing opacity-60" ,
114+ )
115+ }
116+ >
117+ { ( { isHovered, isSelected } ) => (
118+ < >
119+ { dragDisabled ? null : (
120+ < DragAndDropIcon className = "size-4 cursor-grab" />
121+ ) }
122+ < span className = "text-klerosUIComponentsPrimaryText flex-1 text-base" >
123+ { item . name }
124+ </ span >
125+ { isHovered && ! deletionDisabled ? (
126+ < Button
127+ className = { "cursor-pointer hover:scale-105" }
128+ onPress = { ( ) => {
129+ remove ( item . id ) ;
130+ } }
131+ >
132+ { ( { isHovered : isButtonHovered } ) => (
133+ < Trash
134+ className = { clsx (
135+ "ease-ease size-4 transition" ,
136+ ( isButtonHovered || isSelected ) &&
137+ "[&_path]:fill-klerosUIComponentsPrimaryBlue" ,
138+ ) }
139+ />
140+ ) }
141+ </ Button >
142+ ) : null }
143+ </ >
144+ ) }
145+ </ ListBoxItem >
146+ ) ;
147+ } ) }
143148 </ ListBox >
144149 ) ;
145150}
0 commit comments