update: better picker component
This commit is contained in:
parent
8d39e2833c
commit
f4b9257dc9
@ -27,10 +27,27 @@ export default function Picker(props: PickerProps) {
|
||||
return;
|
||||
}
|
||||
const buttonRect = buttonRef.current.getBoundingClientRect();
|
||||
const listWidth = itemListRef.current.getBoundingClientRect().width;
|
||||
const listRect = itemListRef.current.getBoundingClientRect();
|
||||
// Align to center
|
||||
itemListRef.current.style.left = buttonRect.x + buttonRect.width / 2 - listWidth / 2 + "px";
|
||||
itemListRef.current.style.top = buttonRect.y + buttonRect.height + 16 + "px";
|
||||
itemListRef.current.style.left =
|
||||
Math.max(
|
||||
Math.min(
|
||||
buttonRect.x + buttonRect.width / 2 - listRect.width / 2,
|
||||
window.screen.width - listRect.width - 16
|
||||
),
|
||||
0
|
||||
) + "px";
|
||||
if (window.screen.height - buttonRect.top < 192) {
|
||||
itemListRef.current.style.transformOrigin = "bottom center";
|
||||
itemListRef.current.style.top = buttonRect.top - listRect.height - 16 + "px";
|
||||
} else {
|
||||
itemListRef.current.style.top = buttonRect.y + buttonRect.height + 16 + "px";
|
||||
}
|
||||
if (listRect.top + listRect.height > window.screen.height - 16) {
|
||||
itemListRef.current.style.height = window.screen.height - listRect.top - 12 + "px";
|
||||
} else {
|
||||
itemListRef.current.style.height = "fit-content";
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -50,8 +67,8 @@ export default function Picker(props: PickerProps) {
|
||||
function toggleDisplay(targetState?: boolean) {
|
||||
function hideList() {
|
||||
if (itemListRef.current) {
|
||||
itemListRef.current.style.transitionDuration = "200ms";
|
||||
itemListRef.current.style.opacity = "0%";
|
||||
itemListRef.current.style.transform = "scaleX(.85) scaleY(.85)";
|
||||
}
|
||||
setTimeout(() => {
|
||||
setDisplayList(false);
|
||||
@ -60,10 +77,20 @@ export default function Picker(props: PickerProps) {
|
||||
function showList() {
|
||||
setDisplayList(true);
|
||||
setTimeout(() => {
|
||||
if (!itemListRef.current || !buttonRef.current) {
|
||||
return;
|
||||
}
|
||||
updatePosition();
|
||||
if (itemListRef.current) {
|
||||
itemListRef.current.style.opacity = "100%";
|
||||
itemListRef.current.style.transform = "scaleX(1) scaleY(1)";
|
||||
if (window.screen.height - buttonRef.current.getBoundingClientRect().top < 128) {
|
||||
itemListRef.current.style.transformOrigin = "bottom center";
|
||||
}
|
||||
itemListRef.current.style.transitionDuration = "100ms";
|
||||
itemListRef.current.style.opacity = "100%";
|
||||
updatePosition();
|
||||
const listRect = itemListRef.current.getBoundingClientRect();
|
||||
if (listRect.top < 8) {
|
||||
itemListRef.current.style.height = window.screen.height - 8 + "px";
|
||||
itemListRef.current.style.top = "8px";
|
||||
}
|
||||
}, 20);
|
||||
}
|
||||
@ -112,34 +139,37 @@ interface PickerListProps {
|
||||
}
|
||||
|
||||
const PickerList = React.forwardRef<HTMLDivElement, PickerListProps>((props, ref) => {
|
||||
const { selected, selectionOnChange, selectionItems } = props;
|
||||
const { selected, selectionOnChange, selectionItems, toggleDisplay } = props;
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
ref={ref}
|
||||
className="absolute w-fit text-black dark:text-white opacity-0 duration-200
|
||||
bg-zinc-50 shadow-lg border-1 border-zinc-200 dark:border-zinc-600 dark:bg-zinc-700 px-2 py-2 rounded-xl text-align-left scale-[.85]"
|
||||
style={{ transformOrigin: "top center" }}
|
||||
>
|
||||
{Object.keys(selectionItems).map((key: string, index) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="relative py-2 w-full min-w-32 pl-2 cursor-pointer rounded-lg
|
||||
hover:bg-zinc-200 dark:hover:bg-zinc-600 flex justify-between items-center"
|
||||
onClick={() => {
|
||||
selectionOnChange(key);
|
||||
props.toggleDisplay();
|
||||
}}
|
||||
>
|
||||
<span>{selectionItems[key]}</span>
|
||||
<div className="relative w-16"></div>
|
||||
{key === selected && (
|
||||
<Icon className="relative right-2" icon="carbon:checkmark" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<div className="absolute w-screen h-screen" onClick={()=>{toggleDisplay(false)}}>
|
||||
<div
|
||||
ref={ref}
|
||||
className="overflow-y-auto fixed w-fit text-black dark:text-white opacity-0 duration-200
|
||||
bg-zinc-50 shadow-lg border-1 border-zinc-200 dark:border-zinc-600
|
||||
dark:bg-zinc-800 px-2 py-2 rounded-xl text-align-left"
|
||||
style={{ transformOrigin: "top center" }}
|
||||
>
|
||||
{Object.keys(selectionItems).map((key: string, index) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="relative py-2 w-full min-w-32 pl-2 cursor-pointer rounded-lg
|
||||
hover:bg-zinc-200 dark:hover:bg-zinc-700 flex justify-between items-center"
|
||||
onClick={() => {
|
||||
selectionOnChange(key);
|
||||
toggleDisplay(false);
|
||||
}}
|
||||
>
|
||||
<span>{selectionItems[key]}</span>
|
||||
<div className="relative w-16"></div>
|
||||
{key === selected && (
|
||||
<Icon className="relative right-2" icon="carbon:checkmark" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sparkhome",
|
||||
"private": false,
|
||||
"version": "5.2.2",
|
||||
"version": "5.2.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun server.ts",
|
||||
|
@ -12,7 +12,7 @@ export default function Homepage() {
|
||||
const setBgFocus = useSetAtom(bgFocusAtom);
|
||||
|
||||
return (
|
||||
<div className="h-full fixed overflow-hidden w-full bg-black">
|
||||
<div className="h-screen fixed overflow-hidden w-screen bg-black">
|
||||
<Background />
|
||||
<EngineSelector
|
||||
className="absolute top-20 lg:top-44 short:top-0 translate-x-[-50%] translate-y-[-0.2rem]
|
||||
|
Loading…
Reference in New Issue
Block a user