fix: make all apps category tab scrollable (#5113)
* feat: make left and right button workable * refactor: separate category tab into a seperate component to reduce unnecessary re-rendering while scrolling through the arrow buttons. Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: alannnc <alannnc@gmail.com>pull/5132/head^2
parent
bb45b9617b
commit
bc6f959c7a
|
@ -38,29 +38,27 @@ export function useShouldShowArrows() {
|
|||
|
||||
type AllAppsPropsType = { apps: (App & { credentials: Credential[] | undefined })[] };
|
||||
|
||||
export default function AllApps({ apps }: AllAppsPropsType) {
|
||||
interface CategoryTabProps {
|
||||
selectedCategory: string | null;
|
||||
categories: string[];
|
||||
}
|
||||
|
||||
function CategoryTab({ selectedCategory, categories }: CategoryTabProps) {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
const [appsContainerRef] = useAutoAnimate<HTMLDivElement>();
|
||||
const { ref, calculateScroll, leftVisible, rightVisible } = useShouldShowArrows();
|
||||
const categories = apps
|
||||
.map((app) => app.category)
|
||||
.filter((cat, pos, self) => {
|
||||
return self.indexOf(cat) === pos;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const queryCategory =
|
||||
typeof router.query.category === "string" && categories.includes(router.query.category)
|
||||
? router.query.category
|
||||
: null;
|
||||
setSelectedCategory(queryCategory);
|
||||
}, [router.query.category]);
|
||||
const handleLeft = () => {
|
||||
if (ref.current) {
|
||||
ref.current.scrollLeft -= 100;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRight = () => {
|
||||
if (ref.current) {
|
||||
ref.current.scrollLeft += 100;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="mb-16">
|
||||
<div className="relative mb-4 flex flex-col justify-between lg:flex-row lg:items-center">
|
||||
<h2 className="text-lg font-semibold text-gray-900 ">
|
||||
{t("explore_apps", {
|
||||
|
@ -70,12 +68,12 @@ export default function AllApps({ apps }: AllAppsPropsType) {
|
|||
})}
|
||||
</h2>
|
||||
{leftVisible && (
|
||||
<div className="absolute top-9 flex md:left-1/2 md:-top-1">
|
||||
<button onClick={handleLeft} className="absolute top-9 flex md:left-1/2 md:-top-1">
|
||||
<div className="flex h-12 w-5 items-center justify-end bg-white">
|
||||
<ChevronLeft className="h-4 w-4 text-gray-500" />
|
||||
</div>
|
||||
<div className="flex h-12 w-5 bg-gradient-to-l from-transparent to-white" />
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
<ul
|
||||
className="no-scrollbar mt-3 flex max-w-full space-x-1 overflow-x-auto lg:mt-0 lg:max-w-[50%]"
|
||||
|
@ -112,14 +110,40 @@ export default function AllApps({ apps }: AllAppsPropsType) {
|
|||
))}
|
||||
</ul>
|
||||
{rightVisible && (
|
||||
<div className="absolute top-9 right-0 flex md:-top-1">
|
||||
<button onClick={handleRight} className="absolute top-9 right-0 flex md:-top-1">
|
||||
<div className="flex h-12 w-5 bg-gradient-to-r from-transparent to-white" />
|
||||
<div className="flex h-12 w-5 items-center justify-end bg-white">
|
||||
<ChevronRight className="h-4 w-4 text-gray-500" />
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AllApps({ apps }: AllAppsPropsType) {
|
||||
const router = useRouter();
|
||||
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
const [appsContainerRef] = useAutoAnimate<HTMLDivElement>();
|
||||
|
||||
const categories = apps
|
||||
.map((app) => app.category)
|
||||
.filter((cat, pos, self) => {
|
||||
return self.indexOf(cat) === pos;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const queryCategory =
|
||||
typeof router.query.category === "string" && categories.includes(router.query.category)
|
||||
? router.query.category
|
||||
: null;
|
||||
setSelectedCategory(queryCategory);
|
||||
}, [router.query.category]);
|
||||
|
||||
return (
|
||||
<div className="mb-16">
|
||||
<CategoryTab selectedCategory={selectedCategory} categories={categories} />
|
||||
<div
|
||||
className="grid gap-3 lg:grid-cols-4 [@media(max-width:1270px)]:grid-cols-3 [@media(max-width:730px)]:grid-cols-2 [@media(max-width:500px)]:grid-cols-1"
|
||||
ref={appsContainerRef}>
|
||||
|
|
Loading…
Reference in New Issue