feat: add bucket browser

This commit is contained in:
2024-08-19 02:28:25 +07:00
parent 934e0c409c
commit 93a1dce5f7
35 changed files with 770 additions and 137 deletions
+6 -3
View File
@@ -8,7 +8,7 @@ export type Tab = {
name: string;
title?: string;
icon?: LucideIcon;
Component?: () => JSX.Element;
Component?: () => JSX.Element | null;
};
type Props = {
@@ -36,13 +36,16 @@ const TabView = ({
<>
<Tabs
variant="boxed"
className={cn("w-auto inline-flex flex-row items-stretch", className)}
className={cn(
"w-auto inline-flex flex-row items-stretch overflow-x-auto",
className
)}
>
{tabs.map(({ icon: Icon, ...tab }) => (
<Tabs.Tab
key={tab.name}
active={curTab === tab.name}
className="flex flex-row items-center gap-x-2 h-auto"
className="flex flex-row items-center gap-x-2 h-auto shrink-0"
onClick={() => {
setSearchParams((params) => {
params.set(name, tab.name);
+49
View File
@@ -0,0 +1,49 @@
import { useEffect, useRef, useState } from "react";
import Button from "./button";
import { ArrowUp } from "lucide-react";
import { cn } from "@/lib/utils";
const GotoTopButton = () => {
const mainElRef = useRef<HTMLElement | null>(null);
const [show, setShow] = useState(false);
useEffect(() => {
const mainEl = document.querySelector("main");
if (!mainEl) return;
mainElRef.current = mainEl;
const onScroll = () => {
if (mainEl.scrollTop > 300) {
setShow(true);
} else {
setShow(false);
}
};
mainEl.addEventListener("scroll", onScroll);
return () => mainEl.removeEventListener("scroll", onScroll);
}, []);
const onClick = () => {
const mainEl = mainElRef.current;
if (!mainEl) return;
mainEl.scrollTo({ top: 0, behavior: "smooth" });
};
return (
<Button
icon={ArrowUp}
className={cn(
"fixed bottom-4 right-4 invisible opacity-0 transition-opacity",
show && "visible opacity-100"
)}
onClick={onClick}
>
Top
</Button>
);
};
export default GotoTopButton;
+1
View File
@@ -46,6 +46,7 @@ export const ToggleField = <T extends FieldValues>({
{...props}
{...field}
className={inputClassName}
color={field.value ? "primary" : undefined}
checked={field.value || false}
onChange={(e) => field.onChange(e.target.checked)}
/>