Skip to content

Commit

Permalink
feat: change le fonctionnement du champ autocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
jillro committed Jun 28, 2024
1 parent 3130891 commit 6c4d0c8
Showing 1 changed file with 47 additions and 45 deletions.
92 changes: 47 additions & 45 deletions src/components/Autocomplete.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,16 @@
export let selection: Array<any> = [];
let componentElement: HTMLDivElement;
let inputElement: HTMLInputElement;
let inputValue = "";
let focus = false;
let search = "";
let searchResult: Choice[] = [];
let selectionDisplay: string;
$: selectionDisplay = selection.length
? selection
.map((value) => {
const choice = choices.find((choice) => choice.value === value);
return choice ? choice.label : value;
})
.join(", ") + (focus ? ", " : "")
: "";
$: inputValue = selectionDisplay + search;
$: searchResult = choices.filter((choice) =>
choice.label.toLowerCase().includes(search.toLowerCase()),
$: searchResult = choices.filter(
(choice) =>
choice.label.toLowerCase().includes(search.toLowerCase()) &&
!selection.includes(choice.value),
);
function updateSearch(event: Event) {
const value = (event.target as HTMLInputElement).value;
if (
search === "" &&
value.length < selectionDisplay.length &&
selection.length > 0
) {
selection = selection.slice(0, -1);
search = "";
} else if (value.startsWith(selectionDisplay)) {
search = value.replace(selectionDisplay, "");
} else {
(event.target as HTMLInputElement).value = selectionDisplay;
}
}
function focusOut(event: FocusEvent) {
if (!componentElement.contains(event.relatedTarget as Node)) {
focus = false;
Expand All @@ -68,27 +40,40 @@
function addSelection(choice: Choice) {
selection = [...selection, choice.value];
search = "";
inputElement.focus();
focus = false;
}
</script>

<div bind:this={componentElement}>
{#each selection as value (value)}
<input type="hidden" {name} {value} />
{/each}
{#if selection.length > 0}
<ul class="selection">
{#each selection as value (value)}
<li>
<button
on:click|capture|stopImmediatePropagation|stopPropagation|preventDefault={() =>
(selection = selection.filter((v) => v !== value))}
>
x
</button>
{choices.find((choice) => choice.value === value)?.label}
</li>
{/each}
</ul>
{/if}
<input
bind:this={inputElement}
type="text"
{id}
{required}
value={inputValue}
on:input={updateSearch}
bind:value={search}
on:focus={() => (focus = true)}
on:blur={focusOut}
on:focusout={focusOut}
on:keydown={inputKeydown}
/>
{#if focus}
<ul>
<ul class="choices">
{#each searchResult as choice (choice.value)}
<li>
<button
Expand All @@ -105,7 +90,24 @@
</div>

<style>
ul {
ul.selection {
list-style-type: none;
}
ul.selection button {
border: 0;
background-color: transparent;
cursor: pointer;
height: 1.5rem;
width: 1.5rem;
color: #666;
&:hover {
background-color: #f9f9f9;
}
}
ul.choices {
list-style-type: none;
padding: 0;
margin: 0;
Expand All @@ -114,19 +116,19 @@
overflow-y: auto;
}
li {
ul.choices li {
padding: 0;
cursor: pointer;
}
button {
ul.choices li:hover {
background-color: #f9f9f9;
}
ul.choices button {
text-align: left;
border: 0;
padding: 0.5rem;
width: 100%;
}
li:hover {
background-color: #f9f9f9;
}
</style>

0 comments on commit 6c4d0c8

Please sign in to comment.