Create dropdown component;
This commit is contained in:
parent
d8a42b48b1
commit
5cde16d777
3 changed files with 68 additions and 5 deletions
56
frontend/components/Dropdown.vue
Normal file
56
frontend/components/Dropdown.vue
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
options: { id: number, name: string }[] | string[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
select: [item: string | number]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const open = ref(false)
|
||||||
|
|
||||||
|
const select = function (item) {
|
||||||
|
emit('select', typeof item === 'object' ? item.id : item)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<PrimaryButton @click="open = !open">
|
||||||
|
<slot /> ↓
|
||||||
|
</PrimaryButton>
|
||||||
|
|
||||||
|
<ul v-show="open" v-bind="$attrs">
|
||||||
|
<li v-for="(item, index) in options" :key="index" @click="select(item)">
|
||||||
|
<template v-if="typeof item === 'object'">
|
||||||
|
{{ item.name }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
{{ item }}
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="postcss">
|
||||||
|
div {
|
||||||
|
@apply w-max inline-block relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@apply absolute z-10 mt-3;
|
||||||
|
@apply rounded-xl;
|
||||||
|
@apply border-pink-400 border-2;
|
||||||
|
@apply bg-gradient-to-br from-pink-400 via-fuchsia-300 to-cyan-400 bg-fixed;
|
||||||
|
|
||||||
|
li {
|
||||||
|
@apply bg-white bg-opacity-30;
|
||||||
|
@apply w-full px-5 py-1.5;
|
||||||
|
@apply first:rounded-t-xl last:rounded-b-xl;
|
||||||
|
@apply transition-colors duration-200 hover:text-pink-500;
|
||||||
|
@apply cursor-pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -3,7 +3,9 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<table><slot /></table>
|
<table>
|
||||||
|
<slot />
|
||||||
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
@ -14,10 +16,10 @@ table {
|
||||||
.actions {
|
.actions {
|
||||||
@apply text-end;
|
@apply text-end;
|
||||||
|
|
||||||
a {
|
& > * {
|
||||||
@apply me-3;
|
@apply me-3;
|
||||||
|
|
||||||
@apply last-of-type:me-0;
|
@apply last:me-0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,6 +15,7 @@ const mediaList = computed(() => {
|
||||||
<TableTh>Copies</TableTh>
|
<TableTh>Copies</TableTh>
|
||||||
<TableTh>Checked Out</TableTh>
|
<TableTh>Checked Out</TableTh>
|
||||||
<TableTh actions>
|
<TableTh actions>
|
||||||
|
<Dropdown :options="['books', 'films', 'albums']">Type</Dropdown>
|
||||||
<PrimaryButton>Add New</PrimaryButton>
|
<PrimaryButton>Add New</PrimaryButton>
|
||||||
</TableTh>
|
</TableTh>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -31,7 +32,9 @@ const mediaList = computed(() => {
|
||||||
|
|
||||||
<TableTd>
|
<TableTd>
|
||||||
<div>{{ media.checkedOut }}</div>
|
<div>{{ media.checkedOut }}</div>
|
||||||
<SecondaryInfo>{{ media.holds.length }} on hold</SecondaryInfo>
|
<SecondaryInfo v-if="media.holds.length > 0">
|
||||||
|
{{ media.holds.length }} on hold
|
||||||
|
</SecondaryInfo>
|
||||||
</TableTd>
|
</TableTd>
|
||||||
|
|
||||||
<TableTd actions>
|
<TableTd actions>
|
||||||
|
@ -46,5 +49,7 @@ const mediaList = computed(() => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="postcss">
|
<style scoped lang="postcss">
|
||||||
|
section {
|
||||||
|
@apply w-full px-10;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue