mirror of
https://github.com/immich-app/immich.git
synced 2025-01-27 22:22:45 +01:00
chore: refactoring and cleanup
This commit is contained in:
parent
8c74d89420
commit
fdd0729c4a
2 changed files with 27 additions and 31 deletions
web/src/lib/components/shared-components
|
@ -53,20 +53,17 @@
|
|||
let optionRefs: HTMLElement[] = [];
|
||||
let input: HTMLInputElement;
|
||||
let bounds: DOMRect | undefined;
|
||||
let scrollable: Element | null;
|
||||
let direction: 'bottom' | 'top' = 'bottom';
|
||||
let scrollableAncestor: Element | null;
|
||||
let dropdownDirection: 'bottom' | 'top' = 'bottom';
|
||||
|
||||
const inputId = `combobox-${id}`;
|
||||
const listboxId = `listbox-${id}`;
|
||||
const dropdownOffset = 15;
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
for (const entry of entries) {
|
||||
if (entry.intersectionRatio < 1) {
|
||||
isOpen = false;
|
||||
}
|
||||
const inputEntry = entries[0];
|
||||
if (inputEntry.intersectionRatio < 1) {
|
||||
isOpen = false;
|
||||
}
|
||||
},
|
||||
{ threshold: 0.5 },
|
||||
|
@ -80,20 +77,14 @@
|
|||
|
||||
$: position = calculatePosition(bounds);
|
||||
|
||||
$: {
|
||||
if (input) {
|
||||
scrollable?.removeEventListener('scroll', onPositionChange);
|
||||
scrollable = input.closest('.overflow-y-auto, .overflow-y-scroll');
|
||||
scrollable?.addEventListener('scroll', onPositionChange);
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
observer.observe(input);
|
||||
scrollableAncestor = input.closest('.overflow-y-auto, .overflow-y-scroll');
|
||||
scrollableAncestor?.addEventListener('scroll', onPositionChange);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
scrollable?.removeEventListener('scroll', onPositionChange);
|
||||
scrollableAncestor?.removeEventListener('scroll', onPositionChange);
|
||||
observer.disconnect();
|
||||
});
|
||||
|
||||
|
@ -158,7 +149,7 @@
|
|||
};
|
||||
|
||||
const calculatePosition = (boundary: DOMRect | undefined) => {
|
||||
direction = getComboboxDirection(boundary);
|
||||
dropdownDirection = getComboboxDirection(boundary);
|
||||
|
||||
if (!boundary) {
|
||||
return undefined;
|
||||
|
@ -166,12 +157,12 @@
|
|||
|
||||
const viewportHeight = window.innerHeight;
|
||||
|
||||
if (direction === 'top') {
|
||||
if (dropdownDirection === 'top') {
|
||||
return {
|
||||
bottom: `${viewportHeight - boundary.top}px`,
|
||||
left: `${boundary.left}px`,
|
||||
width: `${boundary.width}px`,
|
||||
maxHeight: `${boundary.top - dropdownOffset}px`,
|
||||
maxHeight: maxHeight(boundary.top - dropdownOffset),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -180,10 +171,14 @@
|
|||
top: `${boundary.bottom}px`,
|
||||
left: `${boundary.left}px`,
|
||||
width: `${boundary.width}px`,
|
||||
maxHeight: `${availableHeight - dropdownOffset}px`,
|
||||
maxHeight: maxHeight(availableHeight - dropdownOffset),
|
||||
};
|
||||
};
|
||||
|
||||
const maxHeight = (size: number) => {
|
||||
return `min(${size}px,18rem)`;
|
||||
};
|
||||
|
||||
const onPositionChange = () => {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
|
@ -197,9 +192,10 @@
|
|||
}
|
||||
|
||||
const viewportHeight = window.innerHeight;
|
||||
const availableHeight = viewportHeight - boundary.bottom;
|
||||
const heightBelow = viewportHeight - boundary.bottom;
|
||||
const heightAbove = boundary.top;
|
||||
|
||||
return availableHeight > 150 ? 'bottom' : 'top';
|
||||
return heightBelow <= 225 && heightAbove > heightBelow ? 'top' : 'bottom';
|
||||
};
|
||||
|
||||
const getInputPosition = () => input?.getBoundingClientRect();
|
||||
|
@ -238,8 +234,8 @@
|
|||
autocomplete="off"
|
||||
bind:this={input}
|
||||
class:!pl-8={isActive}
|
||||
class:!rounded-b-none={isOpen && direction === 'bottom'}
|
||||
class:!rounded-t-none={isOpen && direction === 'top'}
|
||||
class:!rounded-b-none={isOpen && dropdownDirection === 'bottom'}
|
||||
class:!rounded-t-none={isOpen && dropdownDirection === 'top'}
|
||||
class:cursor-pointer={!isActive}
|
||||
class="immich-form-input text-sm text-left w-full !pr-12 transition-all"
|
||||
id={inputId}
|
||||
|
@ -307,15 +303,15 @@
|
|||
id={listboxId}
|
||||
transition:fly={{ duration: 250 }}
|
||||
class="fixed text-left text-sm w-full overflow-y-auto bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-900 z-[10000]"
|
||||
class:rounded-b-xl={direction === 'bottom'}
|
||||
class:rounded-t-xl={direction === 'top'}
|
||||
class:shadow={direction === 'bottom'}
|
||||
class:rounded-b-xl={dropdownDirection === 'bottom'}
|
||||
class:rounded-t-xl={dropdownDirection === 'top'}
|
||||
class:shadow={dropdownDirection === 'bottom'}
|
||||
class:border={isOpen}
|
||||
style:top={position?.top}
|
||||
style:bottom={position?.bottom}
|
||||
style:left={position?.left}
|
||||
style:width={position?.width}
|
||||
style:max-height="min({position?.maxHeight},18rem)"
|
||||
style:max-height={position?.maxHeight}
|
||||
tabindex="-1"
|
||||
>
|
||||
{#if isOpen}
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
aria-modal="true"
|
||||
aria-labelledby={titleId}
|
||||
>
|
||||
<div class="immich-scrollbar overflow-y-auto py-1">
|
||||
<div class="immich-scrollbar overflow-y-auto pt-1" class:pb-4={isStickyBottom}>
|
||||
<ModalHeader id={titleId} {title} {showLogo} {icon} {onClose} />
|
||||
<div class="px-5 pt-0">
|
||||
<slot />
|
||||
|
|
Loading…
Reference in a new issue