refactor to UI components

This commit is contained in:
2023-05-26 00:50:19 +02:00
parent b89816ecd5
commit 9ca0bba526
20 changed files with 160 additions and 78 deletions

View File

@@ -45,16 +45,11 @@ const handleKeypress = (event: { [key: string]: number }) => {
defineExpose({ handleKeypress })
</script>
<template>
<ul
tabindex="0"
class="menu rounded-md border-[1px] bg-base-100 p-2 text-[0.875rem] text-black shadow-md"
>
<li class="flex flex-row" @click="emit('createLink', props.autocompleteText)">
<a class="flex-grow px-2 py-1" :class="!activeResult && 'active'">
<span class="flex-grow">{{ props.autocompleteText }}</span>
<i class="fas fa-plus-circle ml-auto text-white" />
</a>
</li>
<UIMenu class="border-[1px] p-2 text-[0.875rem] text-black shadow-md" :compact="true">
<UIMenuItem :active="!activeResult" @click="emit('createLink', props.autocompleteText)">
<span class="flex-grow">{{ props.autocompleteText }}</span>
<i class="fas fa-plus-circle ml-auto text-white" />
</UIMenuItem>
<SearchResult
v-for="result in results"
:key="result.id"
@@ -62,5 +57,5 @@ defineExpose({ handleKeypress })
:active-result="activeResult"
@go-to-note="emit('createLink', result.title)"
/>
</ul>
</UIMenu>
</template>

View File

@@ -5,22 +5,18 @@ const props = defineProps<{
}>()
</script>
<template>
<div class="card mt-3 border-[1px]" v-if="props.references.length > 0">
<div class="card-body px-3 py-3">
<ul class="menu rounded-md">
<li class="menu-title !opacity-100">
<span class="card-title text-secondary">
References
<div class="badge-outline badge">{{ props.references.length }}</div>
</span>
</li>
<li v-for="reference in props.references" :key="reference.id">
<a class="rounded-md" @click="setActiveNote(reference.id)">
<i class="far fa-file-alt fa-fw" />
{{ reference.title }}
</a>
</li>
</ul>
</div>
</div>
<UIMenu class="mt-3 rounded-xl border-[1px] px-3 py-3" v-if="props.references.length > 0">
<UIMenuItem :title="true">
<span>References</span>
<UIBadge variant="outline">{{ props.references.length }}</UIBadge>
</UIMenuItem>
<UIMenuItem
v-for="reference in props.references"
:key="reference.id"
@click="setActiveNote(reference.id)"
>
<i class="far fa-file-alt fa-fw" />
{{ reference.title }}
</UIMenuItem>
</UIMenu>
</template>

View File

@@ -66,7 +66,7 @@ const resultsRefs = ref<InstanceType<typeof SearchResult>[]>([])
@keydown="handleKeydown"
/>
<div class="z-1000 absolute left-0 right-0 top-[100%]" v-if="active">
<ul tabindex="0" class="menu mt-1 w-full rounded-md bg-base-100 p-2 text-black shadow">
<UIMenu :compact="true" class="mt-1 w-full rounded-md bg-base-100 p-2 text-black shadow">
<div class="max-h-[320px] w-full overflow-y-auto">
<template v-if="results.length > 0">
<SearchResult
@@ -78,9 +78,9 @@ const resultsRefs = ref<InstanceType<typeof SearchResult>[]>([])
ref="resultsRefs"
/>
</template>
<li v-else><a>No notes found</a></li>
<UIMenuItem :compact="true" v-else>No notes found</UIMenuItem>
</div>
</ul>
</UIMenu>
</div>
</div>
</template>

View File

@@ -14,21 +14,15 @@ const emit = defineEmits<{
const element = ref<HTMLElement | null>(null)
</script>
<template>
<li class="flex w-full flex-row" ref="element">
<a
class="items-center px-2 py-1 w-full"
@click.stop.prevent="() => emit('goToNote', element)"
@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-grow overflow-hidden whitespace-nowrap">{{ result.title }}</span>
<span class="whitespace-nowrap">{{ formatDate(result.modified) }}</span>
</a>
</li>
<UIMenuItem
class="flex w-full items-center"
@click.stop.prevent="() => emit('goToNote', element)"
@mousedown.prevent
:disabled="activeNote?.id === result.id"
:active="props.activeResult?.id === result.id"
>
<UIBadge size="sm" variant="ghost" class="mr-0.5" v-if="activeNote?.id === result.id">current</UIBadge>
<span class="flex-grow overflow-hidden whitespace-nowrap">{{ result.title }}</span>
<span class="whitespace-nowrap">{{ formatDate(result.modified) }}</span>
</UIMenuItem>
</template>

View File

@@ -41,7 +41,7 @@ const authModalInitialStateOpen = ref<boolean>(authUI.isPendingRedirect())
<UIButton
size="sm"
variant="outline"
class="search-active-hide py-1 text-white"
class="search-active-hide py-1 text-white topbar-button"
@click="addNote('Untitled new note', '', true)"
>
<i class="fas fa-plus-circle text-[1.1rem]" />
@@ -51,7 +51,7 @@ const authModalInitialStateOpen = ref<boolean>(authUI.isPendingRedirect())
<UIButton
size="sm"
variant="outline"
class="search-active-hide py-1 text-white"
class="search-active-hide py-1 text-white topbar-button"
@click="open"
>
Sign in
@@ -79,7 +79,7 @@ const authModalInitialStateOpen = ref<boolean>(authUI.isPendingRedirect())
#logo:hover {
text-shadow: 0 0 5px white, 0 0 10px white, 0 0 15px white;
}
.btn-outline {
.topbar-button {
@apply hover:border-white hover:bg-white hover:text-primary focus-visible:outline-white;
}

View File

@@ -26,7 +26,7 @@ const handleClick = (fn: (...args: any[]) => any) => {
<OnClickOutside>
<UIDropdown class="search-active-hide">
<template #activator>
<UIButton :dropdown="true" size="sm" variant="outline" class="py-1 text-white">
<UIButton :dropdown="true" size="sm" variant="outline" class="py-1 text-white topbar-button">
<i class="fa-fw fa-solid fa-user-gear" />
</UIButton>
</template>

View File

@@ -93,10 +93,10 @@ const deleteSelectedNotes = (closeModal: () => void) => {
</td>
<td>{{ note.wordCount }}</td>
<td>
<div class="badge" v-if="note.references.length > 0">
<UIBadge v-if="note.references.length > 0">
<i data-v-41bbc26f="" class="fas fa-fw fa-sign-out-alt mr-1"></i>
{{ note.references.length }}
</div>
</UIBadge>
</td>
<td>{{ formatDate(note.modified) }}</td>
</tr>

View File

@@ -7,12 +7,12 @@ const props = withDefaults(defineProps<Props>(), {
})
const styleClass = computed(() => {
const colorClass = `alert-${props.color}`
const colorClass = `dui-alert-${props.color}`
return [colorClass]
})
</script>
<template>
<div class="alert shadow-lg" :class="styleClass">
<div class="dui-alert shadow-lg" :class="styleClass">
<div><slot></slot></div>
</div>
</template>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
interface Props {
size: 'xs' | 'sm' | 'md' | 'lg'
variant?: 'regular' | 'outline' | 'ghost'
}
const props = withDefaults(defineProps<Props>(), {
size: 'md',
variant: 'regular'
})
const styleClass = computed(() => {
const sizeVariants = {
xs: 'dui-badge-xs',
sm: 'dui-badge-sm',
md: 'dui-badge-md',
lg: 'dui-badge-lg'
}
const variantVariants = {
regular: '',
outline: 'dui-badge-outline',
ghost: 'dui-badge-ghost'
}
const sizeClass = sizeVariants[props.size]
const variantClass = variantVariants[props.variant]
return [sizeClass, variantClass]
})
</script>
<template>
<div class="dui-badge" :class="styleClass"><slot></slot></div>
</template>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
interface Props {
size?: string
size?: 'xs' | 'sm' | 'md' | 'lg'
variant?: 'regular' | 'outline'
color?: string
color?: 'regular' | 'primary'
dropdown?: boolean
}
@@ -14,18 +14,29 @@ const props = withDefaults(defineProps<Props>(), {
})
const styleClass = computed(() => {
const colorVariants: { [key: string]: string } = {
primary: 'btn-primary'
const sizeVariants = {
xs: 'dui-btn-xs',
sm: 'dui-btn-sm',
md: 'dui-btn-md',
lg: 'dui-btn-lg'
}
const sizeClass = `btn-${props.size}`
const variantClass = props.variant !== 'regular' ? `btn-${props.variant}` : ''
const colorClass = props.color !== 'regular' ? colorVariants[props.color] : ''
const colorVariants = {
regular: '',
primary: 'dui-btn-primary'
}
const variantVariants = {
regular: '',
outline: 'dui-btn-outline'
}
const sizeClass = sizeVariants[props.size]
const variantClass = variantVariants[props.variant]
const colorClass = colorVariants[props.color]
return [sizeClass, variantClass, colorClass]
})
</script>
<template>
<label class="btn duration-0" :class="styleClass" v-if="props.dropdown" tabindex="0">
<label class="dui-btn duration-0" :class="styleClass" v-if="props.dropdown" tabindex="0">
<slot></slot>
</label>
<button class="btn duration-0" :class="styleClass" v-else><slot></slot></button>
<button class="dui-btn duration-0" :class="styleClass" v-else><slot></slot></button>
</template>

View File

@@ -1,3 +1,3 @@
<template>
<div class="btn-group"><slot></slot></div>
<div class="dui-btn-group"><slot></slot></div>
</template>

View File

@@ -1,9 +1,9 @@
<template>
<div class="dropdown-end dropdown">
<div class="dui-dropdown-end dui-dropdown">
<slot name="activator" tabindex="0"></slot>
<ul
tabindex="0"
class="dropdown-content menu rounded-box menu-compact mt-1 w-52 bg-base-100 p-2 text-base-content shadow"
class="dui-dropdown-content dui-menu dui-menu-compact rounded-box mt-1 w-52 bg-base-100 p-2 text-base-content shadow"
>
<slot name="items"></slot>
</ul>

View File

@@ -1,5 +1,5 @@
<template>
<li class="text-base">
<a><slot></slot></a>
<a class="rounded-lg"><slot></slot></a>
</li>
</template>

View File

@@ -0,0 +1,16 @@
<script setup lang="ts">
interface Props {
compact?: boolean
}
const props = defineProps<Props>()
const styleClass = computed(() => {
const compactClass = props.compact && 'dui-menu-compact'
return [compactClass]
})
</script>
<template>
<ul tabindex="0" class="dui-menu rounded-md bg-base-100" :class="styleClass">
<slot></slot>
</ul>
</template>

View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
interface Props {
title?: boolean
disabled?: boolean
active?: boolean
}
const props = defineProps<Props>()
const styleClass = computed(() => {
const titleClass = props.title
? 'dui-menu-item dui-menu-title !opacity-100 space-x-2 !text-xl font-bold text-secondary'
: ''
return [titleClass]
})
</script>
<template>
<li :class="styleClass">
<span class="flex items-center" v-if="props.title"><slot></slot></span>
<a
class="w-full rounded-md"
:class="{ 'dui-disabled': props.disabled, 'dui-active': props.active }"
v-else
>
<slot></slot>
</a>
</li>
</template>

View File

@@ -52,13 +52,13 @@ defineExpose({ open, close })
<slot name="activator" v-bind="slotProps"></slot>
<Teleport to="body">
<Transition @enter="onEnter" @leave="onLeave" appear>
<div class="modal bg-neutral-800 bg-opacity-60" v-if="show" ref="modal">
<div class="modal-box" ref="modalBox">
<div class="dui-modal bg-neutral-800 bg-opacity-60" v-if="show" ref="modal">
<div class="dui-modal-box" ref="modalBox">
<h3 class="text-lg font-bold" v-if="$slots.title"><slot name="title" /></h3>
<p class="py-4">
<slot v-bind="slotProps" />
</p>
<div class="modal-action">
<div class="dui-modal-action">
<slot name="actions" v-bind="slotProps">
<UIButton size="sm" @click="close">Close</UIButton>
</slot>

View File

@@ -5,11 +5,11 @@ interface Props {
const props = defineProps<Props>()
const styleClass = computed(() => {
const densityClass = props.density ? 'table-compact' : ''
const densityClass = props.density ? 'dui-table-compact' : ''
return [densityClass]
})
</script>
<template>
<table class="table" :class="styleClass"><slot></slot></table>
<table class="dui-table" :class="styleClass"><slot></slot></table>
</template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
interface Props {
modelValue: any
size?: 'sm' | 'md' | 'lg' | 'xl'
size?: 'xs' | 'sm' | 'md' | 'lg'
}
const props = withDefaults(defineProps<Props>(), {
@@ -13,7 +13,13 @@ const emit = defineEmits<{
}>()
const styleClass = computed(() => {
const sizeClass = `input-${props.size}`
const sizeVariants = {
'xs': 'dui-input-xs',
'sm': 'dui-input-sm',
'md': 'dui-input-md',
'lg': 'dui-input-lg'
}
const sizeClass = sizeVariants[props.size]
return [sizeClass]
})
</script>
@@ -22,7 +28,7 @@ const styleClass = computed(() => {
type="text"
:value="props.modelValue"
@input="emit('update:modelValue', ($event.target as HTMLInputElement)?.value)"
class="input-bordered input input-sm my-1 ml-auto mr-1 max-w-xs flex-grow"
class="dui-input-bordered dui-input my-1 ml-auto mr-1 max-w-xs flex-grow"
:class="styleClass"
/>
</template>