mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-26 09:54:43 +10:00
Merge pull request #2202 from Pieczasz/feat/2169-project-tags-order
feat(projects): allow reordering of project item tags
This commit is contained in:
@@ -28,6 +28,10 @@ const formSchema = projectSchema;
|
|||||||
|
|
||||||
type FormValues = z.infer<typeof formSchema>;
|
type FormValues = z.infer<typeof formSchema>;
|
||||||
|
|
||||||
|
const handleDragOver = (e: React.DragEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
export const ProjectsDialog = () => {
|
export const ProjectsDialog = () => {
|
||||||
const form = useForm<FormValues>({
|
const form = useForm<FormValues>({
|
||||||
defaultValues: defaultProject,
|
defaultValues: defaultProject,
|
||||||
@@ -35,6 +39,23 @@ export const ProjectsDialog = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [pendingKeyword, setPendingKeyword] = useState("");
|
const [pendingKeyword, setPendingKeyword] = useState("");
|
||||||
|
const [draggedIndex, setDraggedIndex] = useState<number | null>(null);
|
||||||
|
|
||||||
|
const handleDrop = (
|
||||||
|
e: React.DragEvent,
|
||||||
|
dropIndex: number,
|
||||||
|
field: { value: string[]; onChange: (value: string[]) => void },
|
||||||
|
) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (draggedIndex === null) return;
|
||||||
|
|
||||||
|
const newKeywords = [...field.value];
|
||||||
|
const [draggedItem] = newKeywords.splice(draggedIndex, 1);
|
||||||
|
newKeywords.splice(dropIndex, 0, draggedItem);
|
||||||
|
|
||||||
|
field.onChange(newKeywords);
|
||||||
|
setDraggedIndex(null);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionDialog<FormValues>
|
<SectionDialog<FormValues>
|
||||||
@@ -151,18 +172,28 @@ export const ProjectsDialog = () => {
|
|||||||
<motion.div
|
<motion.div
|
||||||
key={item}
|
key={item}
|
||||||
layout
|
layout
|
||||||
|
draggable
|
||||||
initial={{ opacity: 0, y: -50 }}
|
initial={{ opacity: 0, y: -50 }}
|
||||||
animate={{ opacity: 1, y: 0, transition: { delay: index * 0.1 } }}
|
animate={{ opacity: 1, y: 0, transition: { delay: index * 0.1 } }}
|
||||||
exit={{ opacity: 0, x: -50 }}
|
exit={{ opacity: 0, x: -50 }}
|
||||||
|
onDragStart={() => {
|
||||||
|
setDraggedIndex(index);
|
||||||
|
}}
|
||||||
|
onDragOver={handleDragOver}
|
||||||
|
onDrop={(e) => {
|
||||||
|
handleDrop(e, index, field);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Badge
|
<Badge className="cursor-move">
|
||||||
className="cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
field.onChange(field.value.filter((v) => item !== v));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="mr-1">{item}</span>
|
<span className="mr-1">{item}</span>
|
||||||
<X size={12} weight="bold" />
|
<X
|
||||||
|
className="cursor-pointer"
|
||||||
|
size={12}
|
||||||
|
weight="bold"
|
||||||
|
onClick={() => {
|
||||||
|
field.onChange(field.value.filter((v) => item !== v));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Badge>
|
</Badge>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user