tag-dropdown on touch-device part 2
authorPhiTux <redacted>
Fri, 3 Oct 2025 09:20:19 +0000 (11:20 +0200)
committerPhiTux <redacted>
Fri, 3 Oct 2025 09:20:19 +0000 (11:20 +0200)
frontend/src/lib/Sidenav.svelte
frontend/src/routes/(authed)/write/+page.svelte

index 11e91f62b20a34cab1c8c0b6b83af6d98fdd9731..7900888f3f47fe18d94575825c32358ef5006f2c 100644 (file)
        let showTagDropdown = $state(false);
        let filteredTags = $state([]);
        let selectedTagIndex = $state(0);
+       // Touch-Geräte Erkennung für alternative Tag-Auswahl
+       let isTouchDevice = $state(false);
+       onMount(() => {
+               try {
+                       const ua = navigator.userAgent || '';
+                       const platform = navigator.platform || '';
+                       const maxTP = navigator.maxTouchPoints || 0;
+                       const coarse = window.matchMedia ? window.matchMedia('(pointer: coarse)').matches : false;
+                       const iPadLike = /iPad/.test(ua) || (/Mac/.test(platform) && maxTP > 1);
+                       isTouchDevice = maxTP > 0 || coarse || iPadLike || 'ontouchstart' in window;
+               } catch (e) {
+                       isTouchDevice = false;
+               }
+       });
 
        function handleKeyDown(event) {
                if (!showTagDropdown && event.key === 'Enter') {
                        {/if}
                </form>
                {#if showTagDropdown}
-                       <div class="searchTagDropdown glass">
-                               {#if filteredTags.length === 0}
-                                       <em style="padding: 0.2rem;">
-                                               {$t('tags.no_tags_found')}
-                                       </em>
-                               {:else}
-                                       {#each filteredTags as tag, index (tag.id)}
-                                               <!-- svelte-ignore a11y_click_events_have_key_events -->
-                                               <!-- svelte-ignore a11y_no_static_element_interactions -->
-                                               <!-- svelte-ignore a11y_mouse_events_have_key_events -->
-                                               <div
-                                                       role="button"
-                                                       tabindex="0"
-                                                       onclick={() => selectSearchTag(tag.id)}
-                                                       onmouseover={() => (selectedTagIndex = index)}
-                                                       class="searchTag-item {index === selectedTagIndex ? 'selected' : ''}"
-                                               >
-                                                       <Tag {tag} />
+                       {#if isTouchDevice}
+                               <div class="touch-search-tag-panel glass">
+                                       {#if filteredTags.length === 0}
+                                               <em style="padding: 0.2rem;">{$t('tags.no_tags_found')}</em>
+                                       {:else}
+                                               <div class="touch-tag-grid gap-1">
+                                                       {#each filteredTags as tag (tag.id)}
+                                                               <button
+                                                                       type="button"
+                                                                       class="touch-tag-item btn btn-sm"
+                                                                       onclick={() => selectSearchTag(tag.id)}
+                                                               >
+                                                                       <Tag {tag} />
+                                                               </button>
+                                                       {/each}
                                                </div>
-                                       {/each}
-                               {/if}
-                       </div>
+                                       {/if}
+                               </div>
+                       {:else}
+                               <div class="searchTagDropdown glass">
+                                       {#if filteredTags.length === 0}
+                                               <em style="padding: 0.2rem;">
+                                                       {$t('tags.no_tags_found')}
+                                               </em>
+                                       {:else}
+                                               {#each filteredTags as tag, index (tag.id)}
+                                                       <!-- svelte-ignore a11y_click_events_have_key_events -->
+                                                       <!-- svelte-ignore a11y_no_static_element_interactions -->
+                                                       <!-- svelte-ignore a11y_mouse_events_have_key_events -->
+                                                       <div
+                                                               role="button"
+                                                               tabindex="0"
+                                                               onclick={() => selectSearchTag(tag.id)}
+                                                               onmouseover={() => (selectedTagIndex = index)}
+                                                               class="searchTag-item {index === selectedTagIndex ? 'selected' : ''}"
+                                                       >
+                                                               <Tag {tag} />
+                                                       </div>
+                                               {/each}
+                                       {/if}
+                               </div>
+                       {/if}
                {/if}
                <div class="list-group flex-grow-1 mb-2 glass">
                        {#if $searchResults.length > 0}
                border-bottom-right-radius: 10px;
        }
 
+       .touch-search-tag-panel {
+               padding: 0.5rem 0.6rem 0.6rem;
+               max-height: 35vh;
+               background: rgba(255, 255, 255, 0.08);
+               backdrop-filter: blur(6px);
+               border: 1px solid rgba(255, 255, 255, 0.15);
+       }
+
+       .touch-tag-grid {
+               display: flex;
+               flex-wrap: wrap;
+       }
+
+       .touch-tag-item {
+               cursor: pointer;
+               display: flex;
+               align-items: center;
+               gap: 0.25rem;
+       }
+
+       .touch-tag-item:active {
+               transform: scale(0.96);
+       }
+
        @media (max-width: 1599px) {
                .searchTagDropdown {
                        left: 58px;
                background-color: #b9b9b9;
        }
 
-       /* .searchTag-item.selected {
-               background-color: #b2b4b6;
-       } */
-
        .searchTag-item {
                cursor: pointer;
                padding: 5px;
index 291c495ad3b57cc448d2ef633a4632c085c90209..1fa73ff77e1cc3666c4684cdbc2300e9dac53976 100644 (file)
                                {/if}
                                {#if isTouchDevice && showTouchTagPanel}
                                        <div transition:slide>
-                                               <div class="touch-tag-panel mt-2">
-                                                       {#if $tags.length === 0}
-                                                               <em style="padding:0.2rem;">{$t('tags.no_tags_found')}</em>
-                                                       {:else}
-                                                               <div class="d-flex flex-row flex-wrap gap-1 selectTagTouchDevice">
-                                                                       {#each $tags.filter((t) => !selectedTags.includes(t.id)) as tag (tag.id)}
-                                                                               <button
-                                                                                       type="button"
-                                                                                       class="touch-tag-item btn btn-sm btn-outline-none"
-                                                                                       onclick={() => selectTag(tag.id)}
-                                                                               >
-                                                                                       <Tag {tag} />
-                                                                               </button>
-                                                                       {/each}
-                                                               </div>
-                                                       {/if}
+                                               <div class="pt-2">
+                                                       <div class="touch-tag-panel">
+                                                               {#if $tags.length === 0}
+                                                                       <em style="padding:0.2rem;">{$t('tags.no_tags_found')}</em>
+                                                               {:else}
+                                                                       <div class="d-flex flex-row flex-wrap gap-1 selectTagTouchDevice">
+                                                                               {#each $tags.filter((t) => !selectedTags.includes(t.id)) as tag (tag.id)}
+                                                                                       <button
+                                                                                               type="button"
+                                                                                               class="touch-tag-item btn btn-sm btn-outline-none"
+                                                                                               onclick={() => selectTag(tag.id)}
+                                                                                       >
+                                                                                               <Tag {tag} />
+                                                                                       </button>
+                                                                               {/each}
+                                                                       </div>
+                                                               {/if}
+                                                       </div>
                                                </div>
                                        </div>
                                {/if}
 
 <style>
        .selectTagTouchDevice {
-               background-color: #adadad65;
+               background-color: #9e9e9e65;
                padding: 0.5rem;
                border-radius: 10px;
        }
git clone https://git.99rst.org/PROJECT