|
20 | 20 | // Component |
21 | 21 | <button |
22 | 22 | type="button" |
23 | | - onclick={() => updatingDropdown.toggle()} // Open / close the dropdown. |
| 23 | + onclick={(event) => updatingDropdown.toggle(event)} // Open / close the dropdown. |
24 | 24 | > |
25 | 25 |
|
26 | 26 | <UpdatingDropdown bind:this={updatingDropdown} {taskResult} {isLoggedIn} {onupdate} /> |
|
30 | 30 | import { enhance } from '$app/forms'; |
31 | 31 |
|
32 | 32 | import { Dropdown, DropdownUl, DropdownLi, uiHelpers } from 'svelte-5-ui-lib'; |
| 33 | + import Check from 'lucide-svelte/icons/check'; |
33 | 34 |
|
34 | 35 | import type { TaskResult } from '$lib/types/task'; |
35 | 36 |
|
|
55 | 56 | let dropdownStatus = $state(false); |
56 | 57 | let closeDropdown = dropdown.close; |
57 | 58 |
|
| 59 | + let dropdownX = $state(0); |
| 60 | + let dropdownY = $state(0); |
| 61 | + let isLowerHalfInScreen = $state(false); |
| 62 | +
|
58 | 63 | $effect(() => { |
59 | 64 | activeUrl = $page.url.pathname; |
60 | 65 | dropdownStatus = dropdown.isOpen; |
| 66 | +
|
| 67 | + if (dropdownStatus) { |
| 68 | + document.documentElement.style.setProperty('--dropdown-x', `${dropdownX}px`); |
| 69 | + document.documentElement.style.setProperty('--dropdown-y', `${dropdownY}px`); |
| 70 | + } |
61 | 71 | }); |
62 | 72 |
|
63 | | - export function toggle(): void { |
| 73 | + export function toggle(event?: MouseEvent): void { |
| 74 | + if (event) { |
| 75 | + getDropdownPosition(event); |
| 76 | + } |
| 77 | +
|
64 | 78 | dropdown.toggle(); |
65 | 79 | } |
66 | 80 |
|
| 81 | + function getDropdownPosition(event: MouseEvent): void { |
| 82 | + const rect = (event.currentTarget as HTMLElement).getBoundingClientRect(); |
| 83 | +
|
| 84 | + dropdownX = rect.right; |
| 85 | + dropdownY = rect.bottom; |
| 86 | +
|
| 87 | + isLowerHalfInScreen = rect.top > window.innerHeight / 2; |
| 88 | + } |
| 89 | +
|
| 90 | + function getDropdownClasses(isLower: boolean): string { |
| 91 | + let classes = |
| 92 | + 'absolute w-32 z-[999] shadow-lg pointer-events-auto left-[var(--dropdown-x)] transform -translate-x-full '; |
| 93 | +
|
| 94 | + if (isLower) { |
| 95 | + classes += 'bottom-[calc(100vh-var(--dropdown-y))] mb-5'; |
| 96 | + } else { |
| 97 | + classes += 'top-[var(--dropdown-y)] mt-1'; |
| 98 | + } |
| 99 | + return classes; |
| 100 | + } |
| 101 | +
|
67 | 102 | let selectedSubmissionStatus = $state<SubmissionStatus>(); |
68 | 103 | let showForm = $state(false); |
69 | 104 |
|
|
175 | 210 | }); |
176 | 211 | </script> |
177 | 212 |
|
178 | | -<div class="relative"> |
| 213 | +<div class="fixed inset-0 pointer-events-none z-50 w-full h-full"> |
179 | 214 | <Dropdown |
180 | 215 | {activeUrl} |
181 | 216 | {dropdownStatus} |
182 | 217 | {closeDropdown} |
183 | | - class="absolute w-32 z-20 left-auto right-0 mt-8" |
| 218 | + class={getDropdownClasses(isLowerHalfInScreen)} |
184 | 219 | > |
185 | | - <DropdownUl> |
| 220 | + <DropdownUl class="border rounded-lg shadow"> |
186 | 221 | {#if isLoggedIn} |
187 | 222 | {#each submissionStatusOptions as submissionStatus} |
188 | | - <DropdownLi href="javascript:void(0)" onclick={() => handleClick(submissionStatus)}> |
189 | | - {submissionStatus.labelName} |
190 | | - </DropdownLi> |
| 223 | + {@render dropdownListForSubmissionStatus(taskResult, submissionStatus)} |
191 | 224 | {/each} |
192 | 225 | {:else} |
193 | 226 | <DropdownLi href={SIGNUP_PAGE}>アカウント作成</DropdownLi> |
|
201 | 234 | {/if} |
202 | 235 | </div> |
203 | 236 |
|
| 237 | +{#snippet dropdownListForSubmissionStatus( |
| 238 | + taskResult: TaskResult, |
| 239 | + submissionStatus: SubmissionStatus, |
| 240 | +)} |
| 241 | + <DropdownLi href="javascript:void(0)" onclick={() => handleClick(submissionStatus)}> |
| 242 | + <div class="flex items-center justify-between"> |
| 243 | + {submissionStatus.labelName} |
| 244 | + |
| 245 | + {#if taskResult.status_name === submissionStatus.innerName} |
| 246 | + <Check class="w-4 h-4 text-primary-600 dark:text-gray-300" strokeWidth={3} /> |
| 247 | + {/if} |
| 248 | + </div> |
| 249 | + </DropdownLi> |
| 250 | +{/snippet} |
| 251 | + |
204 | 252 | {#snippet submissionStatusForm(selectedTaskResult: TaskResult, submissionStatus: SubmissionStatus)} |
205 | 253 | <form |
206 | 254 | id="submissionStatusForm" |
|
0 commit comments