2024-07-25 15:31:27 +02:00
|
|
|
import * as React from "bloatless-react";
|
|
|
|
|
|
|
|
|
|
import SearchViewModel from "../../ViewModel/Utility/searchViewModel";
|
2024-07-27 03:41:47 +02:00
|
|
|
import { StringToOption } from "../Components/option";
|
2024-07-25 15:31:27 +02:00
|
|
|
import { translations } from "../translations";
|
2024-07-27 03:41:47 +02:00
|
|
|
import { v4 } from "uuid";
|
2024-07-25 15:31:27 +02:00
|
|
|
|
|
|
|
|
export function SearchModal<T>(
|
2024-07-27 03:41:47 +02:00
|
|
|
searchViewModel: SearchViewModel<T>,
|
2024-07-25 15:31:27 +02:00
|
|
|
headline: string,
|
|
|
|
|
converter: React.StateItemConverter<T>,
|
|
|
|
|
isOpen: React.State<boolean>
|
|
|
|
|
) {
|
|
|
|
|
function close() {
|
|
|
|
|
isOpen.value = false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-27 15:39:04 +02:00
|
|
|
const suggestionId = v4();
|
2024-07-27 03:41:47 +02:00
|
|
|
|
2024-07-25 15:31:27 +02:00
|
|
|
return (
|
|
|
|
|
<div class="modal" toggle:open={isOpen}>
|
|
|
|
|
<div style="max-width: 64rem">
|
|
|
|
|
<main>
|
|
|
|
|
<h2>{headline}</h2>
|
|
|
|
|
<div class="flex-row width-input">
|
|
|
|
|
<input
|
|
|
|
|
placeholder={translations.general.searchLabel}
|
2024-07-27 03:41:47 +02:00
|
|
|
bind:value={searchViewModel.searchInput}
|
|
|
|
|
on:enter={searchViewModel.applySearch}
|
2024-07-27 15:39:04 +02:00
|
|
|
list={suggestionId}
|
2024-07-25 15:31:27 +02:00
|
|
|
></input>
|
2024-07-27 03:41:47 +02:00
|
|
|
<datalist
|
|
|
|
|
hidden
|
2024-07-27 15:39:04 +02:00
|
|
|
id={suggestionId}
|
2024-07-27 03:41:47 +02:00
|
|
|
children:append={[searchViewModel.suggestions, StringToOption]}
|
|
|
|
|
></datalist>
|
2024-07-25 15:31:27 +02:00
|
|
|
<button
|
|
|
|
|
class="primary"
|
|
|
|
|
aria-label={translations.general.searchButtonAudioLabel}
|
2024-07-27 03:41:47 +02:00
|
|
|
on:click={searchViewModel.applySearch}
|
|
|
|
|
toggle:disabled={searchViewModel.cannotApplySearch}
|
2024-07-25 15:31:27 +02:00
|
|
|
>
|
|
|
|
|
<span class="icon">search</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<hr></hr>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
class="grid gap"
|
2024-07-27 01:29:00 +02:00
|
|
|
style="grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr))"
|
2024-07-27 03:41:47 +02:00
|
|
|
children:append={[searchViewModel.matchingObjects, converter]}
|
2024-07-25 15:31:27 +02:00
|
|
|
></div>
|
|
|
|
|
</main>
|
|
|
|
|
<button on:click={close}>
|
|
|
|
|
{translations.general.closeButton}
|
|
|
|
|
<span class="icon">close</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|