Skip to content

Commit

Permalink
fix(ModalBasicLayout): fix for logic of when to show modal footer sha…
Browse files Browse the repository at this point in the history
…dow (#2665)
  • Loading branch information
YossiSaadi authored Dec 19, 2024
1 parent dce7e52 commit 9d68962
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ModalBasicLayout = forwardRef(
{ children, className, id, "data-testid": dataTestId }: ModalBasicLayoutProps,
ref: React.ForwardedRef<HTMLDivElement>
) => {
const { isContentScrolled, onScroll } = useLayoutScrolledContent();
const { ref: contentRef, isContentScrolled, isScrollable, isScrolledToEnd, onScroll } = useLayoutScrolledContent();
const [header, content] = React.Children.toArray(children);

return (
Expand All @@ -30,11 +30,11 @@ const ModalBasicLayout = forwardRef(
>
<div className={styles.header}>{header}</div>
<Divider className={cx(styles.divider, { [styles.showDivider]: isContentScrolled })} withoutMargin />
<ModalLayoutScrollableContent onScroll={onScroll} className={styles.content}>
<ModalLayoutScrollableContent onScroll={onScroll} className={styles.content} ref={contentRef}>
{content}
</ModalLayoutScrollableContent>
</Flex>
<ModalFooterShadow show={isContentScrolled} />
{isScrollable && <ModalFooterShadow show={!isScrolledToEnd} />}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from "react";
import React, { ForwardedRef, forwardRef } from "react";
import cx from "classnames";
import styles from "./ModalLayoutScrollableContent.module.scss";
import { ModalLayoutScrollableContentProps } from "./ModalLayoutScrollableContent.types";

const ModalLayoutScrollableContent = ({ onScroll, className, children }: ModalLayoutScrollableContentProps) => {
return (
<div className={cx(styles.content, className)} onScroll={onScroll}>
{children}
</div>
);
};
const ModalLayoutScrollableContent = forwardRef(
({ onScroll, className, children }: ModalLayoutScrollableContentProps, ref: ForwardedRef<HTMLDivElement>) => {
return (
<div ref={ref} className={cx(styles.content, className)} onScroll={onScroll}>
{children}
</div>
);
}
);

export default ModalLayoutScrollableContent;
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
import { UIEventHandler, useCallback, useState } from "react";
import { UIEventHandler, useCallback, useEffect, useRef, useState } from "react";

const useLayoutScrolledContent = () => {
const [isContentScrolled, setContentScrolled] = useState<boolean>(false);
const [isScrollable, setScrollable] = useState<boolean>(false);
const [isScrolledToEnd, setScrolledToEnd] = useState<boolean>(false);

const onScroll: UIEventHandler<HTMLDivElement> = useCallback(
e => {
setContentScrolled(e.currentTarget?.scrollTop > 0);
},
[setContentScrolled]
);
const ref = useRef<HTMLDivElement>(null);

return { isContentScrolled, onScroll };
const checkScroll = useCallback(() => {
const element = ref.current;
if (element) {
const { scrollTop, scrollHeight, clientHeight } = element;
setScrollable(scrollHeight > clientHeight);
setContentScrolled(scrollTop > 0);
setScrolledToEnd(scrollTop + clientHeight >= scrollHeight);
}
}, []);

const onScroll: UIEventHandler<HTMLDivElement> = useCallback(() => {
checkScroll();
}, [checkScroll]);

useEffect(() => {
const element = ref.current;
if (!element) return;

const resizeObserver = new ResizeObserver(() => {
checkScroll();
});

resizeObserver.observe(element);

checkScroll();

return () => {
resizeObserver.disconnect();
};
}, [checkScroll]);

return { ref, isContentScrolled, isScrollable, isScrolledToEnd, onScroll };
};

export default useLayoutScrolledContent;

0 comments on commit 9d68962

Please sign in to comment.