autocomplete styling
This commit is contained in:
29
src/components/Autocomplete.vue
Normal file
29
src/components/Autocomplete.vue
Normal 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>
|
||||
@@ -15,6 +15,7 @@ import AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat'
|
||||
import ContextedPlugin from '@/ckeditor/ContextedPlugin'
|
||||
import { mdToHtml } from '@/utils/markdown'
|
||||
import { activeNote, getNoteByTitle } from '@/composables/useNotes'
|
||||
import Autocomplete from '@/components/Autocomplete.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
note: Note
|
||||
@@ -92,13 +93,12 @@ const handleAutocomplete = (event: any) => {
|
||||
@click="handleClick"
|
||||
@contexted-link-autocomplete="handleAutocomplete"
|
||||
></CKEditor>
|
||||
<div
|
||||
class="absolute mt-1 border-red-500 bg-primary text-white"
|
||||
:style="autocompleteStyle"
|
||||
<Autocomplete
|
||||
v-if="showAutocomplete"
|
||||
>
|
||||
{{ autocompleteText }}
|
||||
</div>
|
||||
:autocomplete-text="autocompleteText"
|
||||
:style="autocompleteStyle"
|
||||
class="absolute mt-1 w-[250px]"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import SearchResult from '@/components/Search/SearchResult.vue'
|
||||
import { notes, findNotes, activeNote } from '@/composables/useNotes'
|
||||
import { formatDate } from '@/utils/helpers'
|
||||
|
||||
const active = ref(false)
|
||||
watch(active, () => {
|
||||
@@ -62,26 +62,13 @@ const handleKeydown = (event: KeyboardEvent) => {
|
||||
tabindex="0"
|
||||
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">
|
||||
<a
|
||||
class="flex-1 items-center px-2 py-1"
|
||||
@click.stop.prevent="() => goToNote(result)"
|
||||
@mousedown.prevent
|
||||
:class="{
|
||||
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>
|
||||
<SearchResult
|
||||
v-for="result in results"
|
||||
v-if="results.length > 0"
|
||||
:result="result"
|
||||
:active-result="activeResult"
|
||||
@go-to-note="() => goToNote(result)"
|
||||
/>
|
||||
<li v-else><a>No notes found</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
35
src/components/Search/SearchResult.vue
Normal file
35
src/components/Search/SearchResult.vue
Normal 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>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
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 { addNote, activeNote, rootNote } from '@/composables/useNotes'
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -41,6 +41,11 @@ export const getNoteByTitle = (title: string) => {
|
||||
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[] => {
|
||||
const removeMdFromText = (mdText: string): string => {
|
||||
const div = document.createElement('div')
|
||||
|
||||
Reference in New Issue
Block a user