Fix Safari category dropdown and emoji picker event handling

Co-authored-by: seanmorley15 <98704938+seanmorley15@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-10-30 15:51:57 +00:00
parent 7497f97384
commit 485c64ee22
19 changed files with 17731 additions and 17682 deletions

View File

@@ -1,48 +1,48 @@
{
"name": "adventurelog-frontend",
"version": "0.10.0",
"version": "0.11.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "adventurelog-frontend",
"version": "0.10.0",
"version": "0.11.0",
"dependencies": {
"@lukulent/svelte-umami": "^0.0.3",
"dompurify": "^3.2.4",
"emoji-picker-element": "^1.26.0",
"dompurify": "^3.2.5",
"emoji-picker-element": "^1.26.3",
"gsap": "^3.12.7",
"luxon": "^3.6.1",
"marked": "^15.0.4",
"marked": "^15.0.11",
"psl": "^1.15.0",
"qrcode": "^1.5.4",
"svelte-i18n": "^4.0.1",
"svelte-maplibre": "^0.9.8"
"svelte-maplibre": "^0.9.14"
},
"devDependencies": {
"@event-calendar/core": "^3.7.1",
"@event-calendar/day-grid": "^3.7.1",
"@event-calendar/core": "^3.12.0",
"@event-calendar/day-grid": "^3.12.0",
"@event-calendar/interaction": "^3.12.0",
"@event-calendar/time-grid": "^3.7.1",
"@iconify-json/mdi": "^1.1.67",
"@sveltejs/adapter-node": "^5.2.0",
"@sveltejs/adapter-vercel": "^5.4.1",
"@sveltejs/kit": "^2.8.3",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@tailwindcss/typography": "^0.5.13",
"@types/node": "^22.5.4",
"@event-calendar/time-grid": "^3.12.0",
"@iconify-json/mdi": "^1.2.3",
"@sveltejs/adapter-node": "^5.2.12",
"@sveltejs/adapter-vercel": "^5.7.0",
"@sveltejs/kit": "^2.20.7",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@tailwindcss/typography": "^0.5.16",
"@types/node": "^22.15.2",
"@types/qrcode": "^1.5.5",
"autoprefixer": "^10.4.19",
"daisyui": "^4.12.6",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.5",
"autoprefixer": "^10.4.21",
"daisyui": "^4.12.24",
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"prettier-plugin-svelte": "^3.3.3",
"svelte": "^4.2.19",
"svelte-check": "^3.8.1",
"tailwindcss": "^3.4.4",
"tslib": "^2.6.3",
"typescript": "^5.5.2",
"unplugin-icons": "^0.19.0",
"svelte-check": "^3.8.6",
"tailwindcss": "^3.4.17",
"tslib": "^2.8.1",
"typescript": "^5.8.3",
"unplugin-icons": "^0.19.3",
"vite": "^5.4.19"
}
},

View File

@@ -23,11 +23,13 @@
let isOpen: boolean = false;
let isEmojiPickerVisible: boolean = false;
function toggleEmojiPicker() {
function toggleEmojiPicker(event: Event) {
event.stopPropagation();
isEmojiPickerVisible = !isEmojiPickerVisible;
}
function toggleDropdown() {
function toggleDropdown(event: Event) {
event.stopPropagation();
isOpen = !isOpen;
}
@@ -35,9 +37,12 @@
console.log('category', category);
selected_category = category;
isOpen = false;
isEmojiPickerVisible = false;
}
function custom_category() {
function custom_category(event: Event) {
event.preventDefault();
event.stopPropagation();
new_category.name = new_category.display_name.toLowerCase().replace(/ /g, '_');
if (!new_category.icon) {
new_category.icon = '🌎'; // Default icon if none selected
@@ -46,7 +51,16 @@
}
function handleEmojiSelect(event: CustomEvent) {
event.stopPropagation();
new_category.icon = event.detail.unicode;
isEmojiPickerVisible = false;
}
function handleInputKeydown(event: KeyboardEvent) {
if (event.key === 'Enter') {
event.preventDefault();
event.stopPropagation();
}
}
// Close dropdown when clicking outside
@@ -76,9 +90,9 @@
<div class="dropdown w-full" bind:this={dropdownRef}>
<!-- Main dropdown trigger -->
<div
<button
type="button"
tabindex="0"
role="button"
class="btn btn-outline w-full justify-between sm:h-auto h-12"
on:click={toggleDropdown}
>
@@ -98,21 +112,33 @@
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</div>
</button>
{#if isOpen}
<!-- Mobile Modal Overlay (only on small screens) -->
<div class="fixed inset-0 bg-black/50 z-40 sm:hidden" on:click={() => (isOpen = false)}></div>
<div
class="fixed inset-0 bg-black/50 z-40 sm:hidden"
role="presentation"
on:click|stopPropagation={() => (isOpen = false)}
on:keydown={(e) => e.key === 'Escape' && (isOpen = false)}
></div>
<!-- Mobile Bottom Sheet -->
<div
class="fixed bottom-0 left-0 right-0 z-50 bg-base-100 rounded-t-2xl shadow-2xl border-t border-base-300 max-h-[90vh] flex flex-col sm:hidden"
role="dialog"
aria-modal="true"
on:click|stopPropagation
>
<!-- Mobile Header -->
<div class="flex-shrink-0 bg-base-100 border-b border-base-300 p-4">
<div class="flex items-center justify-between">
<h2 class="text-lg font-semibold">{$t('categories.select_category')}</h2>
<button class="btn btn-ghost btn-sm btn-circle" on:click={() => (isOpen = false)}>
<button
type="button"
class="btn btn-ghost btn-sm btn-circle"
on:click|stopPropagation={() => (isOpen = false)}
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
@@ -147,6 +173,8 @@
placeholder={$t('categories.category_name')}
class="input input-bordered w-full h-12 text-base"
bind:value={new_category.display_name}
on:keydown={handleInputKeydown}
on:click|stopPropagation
/>
<div class="join w-full">
<input
@@ -154,6 +182,8 @@
placeholder={$t('categories.icon')}
class="input input-bordered join-item flex-1 h-12 text-base"
bind:value={new_category.icon}
on:keydown={handleInputKeydown}
on:click|stopPropagation
/>
<button
on:click={toggleEmojiPicker}
@@ -184,7 +214,12 @@
</button>
{#if isEmojiPickerVisible}
<div class="p-3 rounded-lg border border-base-300 bg-base-50">
<div
class="p-3 rounded-lg border border-base-300 bg-base-50"
role="dialog"
aria-label="Emoji picker"
on:click|stopPropagation
>
<emoji-picker on:emoji-click={handleEmojiSelect}></emoji-picker>
</div>
{/if}
@@ -204,6 +239,8 @@
placeholder={$t('navbar.search')}
class="input input-bordered w-full h-12 text-base"
bind:value={searchTerm}
on:keydown={handleInputKeydown}
on:click|stopPropagation
/>
</div>
@@ -221,7 +258,7 @@
class:text-primary-content={selected_category &&
selected_category.id === category.id}
class:border-primary={selected_category && selected_category.id === category.id}
on:click={() => selectCategory(category)}
on:click|stopPropagation={() => selectCategory(category)}
>
<div class="flex items-center gap-3 w-full">
<span class="text-2xl flex-shrink-0">{category.icon}</span>
@@ -247,6 +284,7 @@
<!-- Desktop Dropdown -->
<div
class="dropdown-content z-[1] w-full mt-1 bg-base-300 rounded-box shadow-xl border border-base-300 max-h-96 overflow-y-auto hidden sm:block"
on:click|stopPropagation
>
<!-- Desktop Category Creator Section -->
<div class="p-4 border-b border-base-300">
@@ -270,6 +308,8 @@
placeholder={$t('categories.category_name')}
class="input input-bordered input-sm w-full"
bind:value={new_category.display_name}
on:keydown={handleInputKeydown}
on:click|stopPropagation
/>
</div>
<div class="form-control">
@@ -279,6 +319,8 @@
placeholder={$t('categories.icon')}
class="input input-bordered input-sm flex-1"
bind:value={new_category.icon}
on:keydown={handleInputKeydown}
on:click|stopPropagation
/>
<button
on:click={toggleEmojiPicker}
@@ -312,7 +354,12 @@
</div>
{#if isEmojiPickerVisible}
<div class="p-3 rounded-lg border border-base-300">
<div
class="p-3 rounded-lg border border-base-300"
role="dialog"
aria-label="Emoji picker"
on:click|stopPropagation
>
<emoji-picker on:emoji-click={handleEmojiSelect}></emoji-picker>
</div>
{/if}
@@ -340,6 +387,8 @@
placeholder={$t('navbar.search')}
class="input input-bordered input-sm w-full"
bind:value={searchTerm}
on:keydown={handleInputKeydown}
on:click|stopPropagation
/>
</div>
@@ -356,7 +405,7 @@
type="button"
class="btn btn-ghost btn-sm justify-start h-auto py-2 px-3"
class:btn-active={selected_category && selected_category.id === category.id}
on:click={() => selectCategory(category)}
on:click|stopPropagation={() => selectCategory(category)}
role="option"
aria-selected={selected_category && selected_category.id === category.id}
>

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff