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