autocomplete styling

This commit is contained in:
2023-05-04 23:48:39 +02:00
parent e606296585
commit 38a6255e77
6 changed files with 84 additions and 28 deletions

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
import { computed } from 'vue'
import SearchResult from '@/components/Search/SearchResult.vue'
import { notes, findNotesByByTitle, activeNote } from '@/composables/useNotes'
const props = defineProps<{
autocompleteText: string
}>()
const results = computed<Note[]>(() => {
return (
props.autocompleteText ? findNotesByByTitle(props.autocompleteText) : notes.value
).filter((note) => note.id !== activeNote.value?.id)
})
</script>
<template>
<ul
tabindex="0"
class="menu mt-2 w-full rounded-md border-[1px] bg-base-100 p-2 text-[0.875rem] text-black shadow-md"
>
<li class="flex flex-row">
<a class="active flex-1 px-2 py-1">
<span class="flex-1">{{ props.autocompleteText }}</span>
<i class="fas fa-plus-circle ml-auto text-white" />
</a>
</li>
<SearchResult v-for="result in results" :result="result" />
</ul>
</template>

View File

@@ -15,6 +15,7 @@ import AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat'
import ContextedPlugin from '@/ckeditor/ContextedPlugin' import ContextedPlugin from '@/ckeditor/ContextedPlugin'
import { mdToHtml } from '@/utils/markdown' import { mdToHtml } from '@/utils/markdown'
import { activeNote, getNoteByTitle } from '@/composables/useNotes' import { activeNote, getNoteByTitle } from '@/composables/useNotes'
import Autocomplete from '@/components/Autocomplete.vue'
const props = defineProps<{ const props = defineProps<{
note: Note note: Note
@@ -92,13 +93,12 @@ const handleAutocomplete = (event: any) => {
@click="handleClick" @click="handleClick"
@contexted-link-autocomplete="handleAutocomplete" @contexted-link-autocomplete="handleAutocomplete"
></CKEditor> ></CKEditor>
<div <Autocomplete
class="absolute mt-1 border-red-500 bg-primary text-white"
:style="autocompleteStyle"
v-if="showAutocomplete" v-if="showAutocomplete"
> :autocomplete-text="autocompleteText"
{{ autocompleteText }} :style="autocompleteStyle"
</div> class="absolute mt-1 w-[250px]"
/>
</div> </div>
</template> </template>
<style> <style>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, computed } from 'vue' import { ref, watch, computed } from 'vue'
import SearchResult from '@/components/Search/SearchResult.vue'
import { notes, findNotes, activeNote } from '@/composables/useNotes' import { notes, findNotes, activeNote } from '@/composables/useNotes'
import { formatDate } from '@/utils/helpers'
const active = ref(false) const active = ref(false)
watch(active, () => { watch(active, () => {
@@ -62,26 +62,13 @@ const handleKeydown = (event: KeyboardEvent) => {
tabindex="0" tabindex="0"
class="menu mt-1 w-full rounded-md bg-base-100 p-2 text-black shadow" class="menu mt-1 w-full rounded-md bg-base-100 p-2 text-black shadow"
> >
<li v-for="result in results" v-if="results.length > 0" class="flex flex-row"> <SearchResult
<a v-for="result in results"
class="flex-1 items-center px-2 py-1" v-if="results.length > 0"
@click.stop.prevent="() => goToNote(result)" :result="result"
@mousedown.prevent :active-result="activeResult"
:class="{ @go-to-note="() => goToNote(result)"
disabled: activeNote?.id === result.id, />
active: activeResult?.id === result.id,
}"
>
<span
class="badge-ghost badge badge-sm mr-0.5"
v-if="activeNote?.id === result.id"
>
current
</span>
<span class="flex-1">{{ result.title }}</span>
<span>{{ formatDate(result.modified) }}</span>
</a>
</li>
<li v-else><a>No notes found</a></li> <li v-else><a>No notes found</a></li>
</ul> </ul>
</div> </div>

View File

@@ -0,0 +1,35 @@
<script setup lang="ts">
import { activeNote } from '@/composables/useNotes'
import { formatDate } from '@/utils/helpers'
const props = defineProps<{
result: Note
activeResult?: Note
}>()
const emit = defineEmits<{
(e: 'goToNote'): void
}>()
</script>
<template>
<li class="flex flex-row">
<a
class="flex-1 items-center px-2 py-1"
@click.stop.prevent="() => emit('goToNote')"
@mousedown.prevent
:class="{
disabled: activeNote?.id === result.id,
active: props.activeResult?.id === result.id,
}"
>
<span
class="badge-ghost badge badge-sm mr-0.5"
v-if="activeNote?.id === result.id"
>
current
</span>
<span class="flex-1">{{ result.title }}</span>
<span>{{ formatDate(result.modified) }}</span>
</a>
</li>
</template>

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import Hamburger from '@/components/Hamburger.vue' import Hamburger from '@/components/Hamburger.vue'
import SearchBar from '@/components/SearchBar.vue' import SearchBar from '@/components/Search/SearchBar.vue'
import Logo from './Logo.vue' import Logo from './Logo.vue'
import { addNote, activeNote, rootNote } from '@/composables/useNotes' import { addNote, activeNote, rootNote } from '@/composables/useNotes'
const props = defineProps<{ const props = defineProps<{

View File

@@ -41,6 +41,11 @@ export const getNoteByTitle = (title: string) => {
return notes.value.find((note) => note.title === title) return notes.value.find((note) => note.title === title)
} }
export const findNotesByByTitle = (title: string) => {
const titleLowerCase = title.toLowerCase()
return notes.value.filter((note) => note.title.toLowerCase().includes(titleLowerCase))
}
export const findNotes = (query: string): Note[] => { export const findNotes = (query: string): Note[] => {
const removeMdFromText = (mdText: string): string => { const removeMdFromText = (mdText: string): string => {
const div = document.createElement('div') const div = document.createElement('div')