Skip to content

Commit

Permalink
feat(ui): handle keyboard navigation on autocomplete. WF-44
Browse files Browse the repository at this point in the history
  • Loading branch information
madeindjs committed Sep 11, 2024
1 parent d4d7bbd commit a52a5e0
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions src/ui/src/builder/BuilderTemplateInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
:placeholder="props.placeholder"
:list="props.options ? `list-${props.inputId}` : undefined"
@input="handleInput"
@blur="handleBlur"
@blur="closeAutocompletion"
/>
<datalist v-if="props.options" :id="`list-${props.inputId}`">
<option
Expand Down Expand Up @@ -45,24 +45,30 @@
></textarea>
</template>

<div v-if="autocompleteOptions.length" class="fieldStateAutocomplete">
<div
<div
v-if="autocompleteOptions.length"
class="fieldStateAutocomplete"
tabindex="-1"
>
<button
v-for="(option, optionKey) in autocompleteOptions"
:key="optionKey"
class="fieldStateAutocompleteOption"
:value="optionKey"
@focusout="closeAutocompletion"
@focusin="abortClosingAutocompletion"
@click="() => handleComplete(option.text)"
>
<span class="prop">{{ option.text }}</span
><span class="type">{{ option.type }}</span>
</div>
</button>
</div>
</div>
</template>

<script setup lang="ts">
import Fuse from "fuse.js";
import { PropType, inject, nextTick, ref } from "vue";
import { PropType, inject, nextTick, ref, shallowRef } from "vue";
import injectionKeys from "../injectionKeys";
const emit = defineEmits(["input", "update:value"]);
Expand Down Expand Up @@ -90,7 +96,7 @@ const props = defineProps({
});
const ss = inject(injectionKeys.core);
const autocompleteOptions = ref<{ text: string; type: string }[]>([]);
const autocompleteOptions = shallowRef<{ text: string; type: string }[]>([]);
const input = ref<HTMLInputElement | null>(null);
defineExpose({
Expand Down Expand Up @@ -183,11 +189,20 @@ const showAutocomplete = () => {
});
};
const handleBlur = () => {
setTimeout(() => {
let closeAutocompletionJob: ReturnType<typeof setTimeout> | null;
function closeAutocompletion() {
// let some time in case user focused on an autocomplete field
closeAutocompletionJob = setTimeout(() => {
autocompleteOptions.value = [];
closeAutocompletionJob = null;
}, 100);
};
}
function abortClosingAutocompletion() {
if (!closeAutocompletionJob) return;
clearTimeout(closeAutocompletionJob);
closeAutocompletionJob = null;
}
</script>

<style scoped>
Expand All @@ -212,6 +227,13 @@ const handleBlur = () => {
}
.fieldStateAutocompleteOption {
/* reset button style */
background-color: inherit;
border: none;
width: 100%;
text-align: left;
border-radius: 0;
padding: 8px 12px;
cursor: pointer;
display: flex;
Expand All @@ -236,6 +258,7 @@ const handleBlur = () => {
}
.fieldStateAutocompleteOption:hover {
color: inherit;
background-color: var(--builderSubtleHighlightColorSolid);
}
Expand Down

0 comments on commit a52a5e0

Please sign in to comment.