Fix search focus
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { interfaceSearchSuggestions } from '../store';
|
||||
import { getSearchSuggestions } from './Api';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let searchSuggestions = false;
|
||||
interfaceSearchSuggestions.subscribe((value) => (searchSuggestions = value));
|
||||
|
||||
@@ -11,6 +14,8 @@
|
||||
let suggestionsForSearch: string[] = [];
|
||||
let selectedSuggestionIndex: number = -1;
|
||||
|
||||
let showSearchBox = false;
|
||||
|
||||
let debounceTimer: NodeJS.Timeout;
|
||||
function debouncedSearch(event: any) {
|
||||
if (!searchSuggestions) return;
|
||||
@@ -28,6 +33,7 @@
|
||||
function handleSubmit() {
|
||||
selectedSuggestionIndex = -1;
|
||||
goto(`/search/${encodeURIComponent(search)}`);
|
||||
dispatch('searchSubmitted');
|
||||
}
|
||||
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
@@ -50,43 +56,50 @@
|
||||
<form on:submit|preventDefault={handleSubmit}>
|
||||
<div class="field prefix round fill no-margin search">
|
||||
<i class="front">search</i>
|
||||
<input bind:value={search} on:click={() => document.getElementById('search')?.focus()} />
|
||||
<menu class="min">
|
||||
<div class="field large prefix suffix no-margin fixed">
|
||||
<i class="front">arrow_back</i>
|
||||
<input
|
||||
placeholder={$_('searchPlaceholder')}
|
||||
type="text"
|
||||
id="search"
|
||||
required
|
||||
bind:value={search}
|
||||
on:keydown={handleKeyDown}
|
||||
on:keyup={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleSubmit();
|
||||
} else {
|
||||
debouncedSearch(event);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<i class="front" on:click={() => (search = '', suggestionsForSearch = [], selectedSuggestionIndex = -1)}>close</i>
|
||||
</div>
|
||||
{#if searchSuggestions}
|
||||
{#each suggestionsForSearch as suggestion, index}
|
||||
<a
|
||||
on:click={() => {
|
||||
search = suggestion;
|
||||
handleSubmit();
|
||||
<input bind:value={search} on:click={() => (showSearchBox = true)} />
|
||||
{#if showSearchBox}
|
||||
<menu class="min">
|
||||
<div class="field large prefix suffix no-margin fixed">
|
||||
<i class="front" on:click={() => dispatch('searchCancelled')}>arrow_back</i>
|
||||
<input
|
||||
placeholder={$_('searchPlaceholder')}
|
||||
type="text"
|
||||
autofocus={true}
|
||||
required
|
||||
bind:value={search}
|
||||
on:keydown={handleKeyDown}
|
||||
on:keyup={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
handleSubmit();
|
||||
} else {
|
||||
debouncedSearch(event);
|
||||
}
|
||||
}}
|
||||
class="row"
|
||||
class:selected={index === selectedSuggestionIndex}
|
||||
href={`/search/${encodeURIComponent(suggestion)}`}
|
||||
/>
|
||||
<i
|
||||
class="front"
|
||||
on:click={() => (
|
||||
(search = ''), (suggestionsForSearch = []), (selectedSuggestionIndex = -1)
|
||||
)}>close</i
|
||||
>
|
||||
<div>{suggestion}</div>
|
||||
</a>
|
||||
{/each}
|
||||
{/if}
|
||||
</menu>
|
||||
</div>
|
||||
{#if searchSuggestions}
|
||||
{#each suggestionsForSearch as suggestion, index}
|
||||
<a
|
||||
on:click={() => {
|
||||
search = suggestion;
|
||||
handleSubmit();
|
||||
}}
|
||||
class="row"
|
||||
class:selected={index === selectedSuggestionIndex}
|
||||
href={`/search/${encodeURIComponent(suggestion)}`}
|
||||
>
|
||||
<div>{suggestion}</div>
|
||||
</a>
|
||||
{/each}
|
||||
{/if}
|
||||
</menu>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
themeColor
|
||||
} from '../store';
|
||||
|
||||
let mobileSearchShow = false;
|
||||
|
||||
let currentPage: string | null = '';
|
||||
activePage.subscribe((page) => (currentPage = page));
|
||||
|
||||
@@ -290,6 +292,15 @@
|
||||
</nav>
|
||||
|
||||
<nav class="top">
|
||||
{#if !mobileSearchShow}
|
||||
<button
|
||||
on:click={() => (mobileSearchShow = !mobileSearchShow)}
|
||||
class="transparent s circle large"
|
||||
>
|
||||
<i>search</i>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<button class="circle large transparent m l small-margin" data-ui="#menu-expanded"
|
||||
><i>menu</i></button
|
||||
>
|
||||
@@ -297,47 +308,45 @@
|
||||
<Logo classes="m l" />
|
||||
<h6 class="m l">Materialious</h6>
|
||||
|
||||
<div class="max"></div>
|
||||
<div class="max m l"></div>
|
||||
|
||||
<div class="m l">
|
||||
<Search />
|
||||
</div>
|
||||
|
||||
<div class="max"></div>
|
||||
<a
|
||||
href="https://github.com/WardPearce/Materialious"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="button circle large transparent"
|
||||
>
|
||||
<i>code</i>
|
||||
<div class="tooltip bottom">{$_('layout.star')}</div>
|
||||
</a>
|
||||
<button data-ui="#sync-party" class="circle large transparent">
|
||||
<i class:primary-text={$syncPartyPeer}>group</i>
|
||||
<div class="tooltip bottom">{$_('layout.syncParty')}</div>
|
||||
</button>
|
||||
{#if isLoggedIn}
|
||||
<button class="circle large transparent" data-ui="#dialog-notifications"
|
||||
><i>notifications</i>
|
||||
<div class="tooltip bottom">{$_('layout.notifications')}</div>
|
||||
</button>
|
||||
{#if !mobileSearchShow}
|
||||
<div class="max"></div>
|
||||
{/if}
|
||||
<button class="circle large transparent" data-ui="#dialog-settings">
|
||||
<i>settings</i>
|
||||
<div class="tooltip bottom">{$_('layout.settings')}</div>
|
||||
</button>
|
||||
|
||||
{#if !isLoggedIn}
|
||||
<button on:click={login} class="circle large transparent">
|
||||
<i>login</i>
|
||||
<div class="tooltip bottom">{$_('layout.login')}</div>
|
||||
</button>
|
||||
{#if mobileSearchShow}
|
||||
<Search on:searchCancelled={() => (mobileSearchShow = false)} />
|
||||
{:else}
|
||||
<button on:click={logout} class="circle large transparent">
|
||||
<i>logout</i>
|
||||
<div class="tooltip bottom">{$_('layout.logout')}</div>
|
||||
<button data-ui="#sync-party" class="m l circle large transparent">
|
||||
<i class:primary-text={$syncPartyPeer}>group</i>
|
||||
<div class="tooltip bottom">{$_('layout.syncParty')}</div>
|
||||
</button>
|
||||
{#if isLoggedIn}
|
||||
<button class="circle large transparent" data-ui="#dialog-notifications"
|
||||
><i>notifications</i>
|
||||
<div class="tooltip bottom">{$_('layout.notifications')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
<button class="circle large transparent" data-ui="#dialog-settings">
|
||||
<i>settings</i>
|
||||
<div class="tooltip bottom">{$_('layout.settings')}</div>
|
||||
</button>
|
||||
|
||||
{#if !isLoggedIn}
|
||||
<button on:click={login} class="circle large transparent">
|
||||
<i>login</i>
|
||||
<div class="tooltip bottom">{$_('layout.login')}</div>
|
||||
</button>
|
||||
{:else}
|
||||
<button on:click={logout} class="circle large transparent">
|
||||
<i>logout</i>
|
||||
<div class="tooltip bottom">{$_('layout.logout')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
</nav>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user