Clicking outside popover dismisses it
This commit is contained in:
parent
9a09dde557
commit
2a6291a547
7 changed files with 49 additions and 22 deletions
|
|
@ -6,13 +6,15 @@
|
|||
triggerElement: HTMLElement
|
||||
onUpdate: (key: string, value: any) => void
|
||||
onDelete: () => void
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
album = $bindable(),
|
||||
triggerElement,
|
||||
onUpdate,
|
||||
onDelete
|
||||
onDelete,
|
||||
onClose = () => {}
|
||||
}: Props = $props()
|
||||
|
||||
// Convert album date to YYYY-MM-DD format for date input
|
||||
|
|
@ -98,4 +100,5 @@
|
|||
bind:data={popoverData}
|
||||
{triggerElement}
|
||||
onUpdate={handleDateChange}
|
||||
{onClose}
|
||||
/>
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
onUpdate?: (key: string, value: any) => void
|
||||
onAddTag?: () => void
|
||||
onRemoveTag?: (tag: string) => void
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
@ -39,7 +40,8 @@
|
|||
triggerElement,
|
||||
onUpdate = () => {},
|
||||
onAddTag = () => {},
|
||||
onRemoveTag = () => {}
|
||||
onRemoveTag = () => {},
|
||||
onClose = () => {}
|
||||
}: Props = $props()
|
||||
|
||||
let popoverElement: HTMLDivElement
|
||||
|
|
@ -129,9 +131,26 @@
|
|||
window.addEventListener('scroll', handleUpdate, true)
|
||||
window.addEventListener('resize', handleUpdate)
|
||||
|
||||
// Click outside handler
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
const target = event.target as Node
|
||||
// Don't close if clicking inside the trigger button or the popover itself
|
||||
if (
|
||||
triggerElement?.contains(target) ||
|
||||
popoverElement?.contains(target)
|
||||
) {
|
||||
return
|
||||
}
|
||||
onClose()
|
||||
}
|
||||
|
||||
// Add click outside listener
|
||||
document.addEventListener('click', handleClickOutside)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleUpdate, true)
|
||||
window.removeEventListener('resize', handleUpdate)
|
||||
document.removeEventListener('click', handleClickOutside)
|
||||
if (portalTarget) {
|
||||
document.body.removeChild(portalTarget)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
onAddTag: () => void
|
||||
onRemoveTag: (tag: string) => void
|
||||
onDelete: () => void
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
@ -24,7 +25,8 @@
|
|||
triggerElement,
|
||||
onAddTag,
|
||||
onRemoveTag,
|
||||
onDelete
|
||||
onDelete,
|
||||
onClose = () => {}
|
||||
}: Props = $props()
|
||||
|
||||
function handleFieldUpdate(key: string, value: any) {
|
||||
|
|
@ -102,4 +104,5 @@
|
|||
onUpdate={handleFieldUpdate}
|
||||
{onAddTag}
|
||||
{onRemoveTag}
|
||||
{onClose}
|
||||
/>
|
||||
|
|
@ -577,6 +577,7 @@
|
|||
triggerElement={metadataButtonElement}
|
||||
onUpdate={handleMetadataUpdate}
|
||||
onDelete={handleMetadataDelete}
|
||||
onClose={() => isMetadataOpen = false}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@
|
|||
triggerElement={metadataButtonElement}
|
||||
onUpdate={handleMetadataUpdate}
|
||||
onDelete={() => {}}
|
||||
onClose={() => isMetadataOpen = false}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -394,6 +395,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: $unit-2x $unit-3x;
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
font-size: 0.925rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $unit;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.metadata-popover-container {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@
|
|||
onAddTag={addTag}
|
||||
onRemoveTag={removeTag}
|
||||
onDelete={openDeleteConfirmation}
|
||||
onClose={() => showMetadata = false}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -115,25 +115,6 @@
|
|||
}
|
||||
|
||||
|
||||
function handleMetadataPopover(event: MouseEvent) {
|
||||
const target = event.target as Node
|
||||
// Don't close if clicking inside the metadata button or anywhere in a metadata popover
|
||||
if (
|
||||
metadataButtonRef?.contains(target) ||
|
||||
document.querySelector('.metadata-popover')?.contains(target)
|
||||
) {
|
||||
return
|
||||
}
|
||||
showMetadata = false
|
||||
}
|
||||
|
||||
|
||||
$effect(() => {
|
||||
if (showMetadata) {
|
||||
document.addEventListener('click', handleMetadataPopover)
|
||||
return () => document.removeEventListener('click', handleMetadataPopover)
|
||||
}
|
||||
})
|
||||
|
||||
// Mock post object for metadata popover
|
||||
const mockPost = $derived({
|
||||
|
|
@ -190,6 +171,7 @@
|
|||
onAddTag={addTag}
|
||||
onRemoveTag={removeTag}
|
||||
onDelete={() => {}}
|
||||
onClose={() => showMetadata = false}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue