Skip to content

Commit

Permalink
fix: handle scrolling with drag-n-drop
Browse files Browse the repository at this point in the history
  • Loading branch information
navinkarkera committed Dec 13, 2023
1 parent a9d9ecd commit bb0b6d9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
21 changes: 12 additions & 9 deletions src/course-outline/CourseOutline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,17 @@ const CourseOutline = ({ courseId }) => {
title: processingNotificationTitle,
} = useSelector(getProcessingNotification);

const moveSection = useCallback((dragIndex, hoverIndex) => {
const moveSection = useCallback((dragIndex, hoverIndex, dragElement) => {
setSections((prevSections) => {
const newList = update(prevSections, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, prevSections[dragIndex]],
],
});
// set listRef to element that was dragged to make sure scrolling
// uses the correct element while calculating visibility.
listRef.current = dragElement;
return newList;
});
}, []);
Expand All @@ -117,16 +120,16 @@ const CourseOutline = ({ courseId }) => {
};

useEffect(() => {
if (sectionsList) {
setSections((prevSections) => {
if (prevSections.length < sectionsList.length) {
scrollToElement(listRef);
}
return sectionsList;
});
}
setSections(sectionsList);
}, [sectionsList]);

useEffect(() => {
// scrollToElement called in another useEffect to make sure sections are rendered first.
if (listRef.current) {
scrollToElement(listRef.current);
}
}, [sections]);

if (isLoading) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
Expand Down
2 changes: 1 addition & 1 deletion src/course-outline/section-card/SectionCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const SectionCard = forwardRef(({
return;
}
// Time to actually perform the action
moveSection(dragIndex, hoverIndex);
moveSection(dragIndex, hoverIndex, moveRef.current);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
Expand Down
23 changes: 17 additions & 6 deletions src/course-outline/utils.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,23 @@ const getHighlightsFormValues = (currentHighlights) => {
return formValues;
};

const scrollToElement = (ref) => {
ref.current?.scrollIntoView({
block: 'end',
inline: 'nearest',
behavior: 'smooth',
});
/**
* Method to scroll into view port, if it's outside the viewport
*
* @param {Object} target - DOM Element
* @returns {undefined}
*/
const scrollToElement = target => {
if (target.getBoundingClientRect().bottom > window.innerHeight) {
// The bottom of the target will be aligned to the bottom of the visible area of the scrollable ancestor.
target.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
}

// Target is outside the view from the top
if (target.getBoundingClientRect().top < 0) {
// The top of the target will be aligned to the top of the visible area of the scrollable ancestor
target.scrollIntoView({ behavior: 'smooth' });
}
};

export {
Expand Down

0 comments on commit bb0b6d9

Please sign in to comment.