I am currently building a dashboard app and I am facing an issue I can´t solve.
App.vue
<template>
<div class="flex flex-row min-h-screen w-screen">
<SideBar />
<div class="flex flex-col w-full bg-gray-300 shrink min-w-0">
<TopBar />
<RouterView />
</div>
</div>
</template>
Dropdown fragment in TopBar component (flowbite acts normal):
<button
type="button"
class="flex mr-3 text-sm md:mr-0 items-center"
id="user-menu-button"
aria-expanded="false"
data-dropdown-toggle="user-menu"
>
<span class="sr-only">Open user menu</span>
<img
class="w-8 h-8 rounded-full border-green"
src="https://picsum.photos/200"
alt="user photo"
/>
<span class="ml-3 text-medium text-gray-500"
>Hallo, <span class="font-semibold">Leon!</span></span
>
</button>
<!-- Dropdown menu -->
<div
class="
hidden
z-50
my-4
text-base
list-none
bg-white
rounded
divide-y divide-gray-100
shadow
dark:bg-gray-700 dark:divide-gray-600
"
id="user-menu"
style="
position: absolute;
inset: auto auto 0px 0px;
margin: 0px;
transform: translate(1246px, 723px);
"
data-popper-reference-hidden=""
data-popper-escaped=""
data-popper-placement="top"
>
Start of at the RouterView injected Component:
<template>
<main class="w-full h-full py-5 px-5">
<CardStatus />
<Card class="max-w-3xl max-h-80 p-5">
<div class="mb-4 flex flex-row justify-between">
<h5
class="
text-xl
font-semibold
tracking-tight
text-gray-900
dark:text-white
"
>
Dropdown fragment in CardStatus component (flowbite not working):
<button
id="dropdownDefault"
data-dropdown-toggle="dropdown"
class="
text-white
bg-blue-700
hover:bg-blue-800
focus:ring-4 focus:outline-none focus:ring-blue-300
font-medium
rounded-lg
text-sm
px-4
py-2.5
text-center
inline-flex
items-center
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
"
type="button"
>
Dropdown button
<svg
class="w-4 h-4 ml-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
></path>
</svg>
</button>
<!-- Dropdown menu -->
<div
id="dropdown"
class="
z-10
hidden
bg-white
divide-y divide-gray-100
rounded
shadow
w-44
dark:bg-gray-700
"
>
<ul
class="py-1 text-sm text-gray-700 dark:text-gray-200"
aria-labelledby="dropdownDefault"
>
I have no idea why it acts like this. I imported and installed everything like explained in the documentation.
Thanks
Related
I am trying to position a panel to the right of avatar icon. i want to make it look like the supabase dashboard.
i have the following already. iam using tailwindcss and tailwind/headlessui for the popover
<Popover className="relative flex flex-col items-center">
<Popover.Panel
className="absolute -top-32 right-0 z-50 w-screen max-w-[270px] px-4 sm:px-0 translate-x-full ">
<div className="overflow-hidden rounded-sm shadow ring-1 ring-black ring-opacity-5">
<div className="block w-full h-12 bg-blue-50 py-3 px-3 content-center">
<div>
{
(isLoading || isError) ? (
<div role="status" className="space-y-2.5 animate-pulse max-w">
<div className="h-2.5 bg-gray-200 rounded w-full"></div>
</div>
) : (
<h4 className="font-semibold">
{user.email}
</h4>
)
}
</div>
</div>
<div className="relative grid grid-cols-1 gap-4 bg-white py-7 ">
<div className="flex flex-col gap-6">
<PanelItem content="Wishlist" href="/v/wishlist">
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M12.62 20.81C12.28 20.93 11.72 20.93 11.38 20.81C8.48 19.82 2 15.69 2 8.68998C2 5.59998 4.49 3.09998 7.56 3.09998C9.38 3.09998 10.99 3.97998 12 5.33998C13.01 3.97998 14.63 3.09998 16.44 3.09998C19.51 3.09998 22 5.59998 22 8.68998C22 15.69 15.52 19.82 12.62 20.81Z"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</PanelItem>
</div>
</div>
<Button variant="primary" className="rounded-none" onClick={handleSignOut}>
<span className="text-sm font-medium" >Sign Out</span>
</Button>
</div>
</Popover.Panel>
</Popover>
it looks like this.
but should look like this
I am working in Vue js with tailwind CSS, and Flowbite for component library support. But the modal is not working which is a component of flowbite. I have installed and configured flowbite as it is described in the documentation(via NPM then adding it to tailwind.config.js). Other components that flowbite I have tested are working fine.
main.js
import { createPinia } from "pinia";
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import "./assets/main.css";
const pinia = createPinia();
const app = createApp(App);
app.use(pinia);
app.use(router);
app.mount("#app");
modal code
<!-- Modal toggle -->
<button class="block text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" type="button" data-modal-toggle="defaultModal">
Toggle modal
</button>
<!-- Main modal -->
<div id="defaultModal" tabindex="-1" class="overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full justify-center items-center flex" aria-modal="true" role="dialog">
<div class="relative p-4 w-full max-w-2xl h-full md:h-auto">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<!-- Modal header -->
<div class="flex justify-between items-start p-4 rounded-t border-b dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
Terms of Service
</h3>
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="defaultModal">
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<!-- Modal body -->
<div class="p-6 space-y-6">
lore ipsum
</div>
<!-- Modal footer -->
<div class="flex items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
<button data-modal-toggle="defaultModal" type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">I accept</button>
<button data-modal-toggle="defaultModal" type="button" class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">Decline</button>
</div>
</div>
</div>
</div>
I could not figure out this problem of flowbite in vue, then I used https://tailwind-elements.com/ and it's working fine.
If you add the following line in your "./index.html" file:
<script type="module" src="./node_modules/flowbite/dist/flowbite.js"></script>
it works as expected.
I am trying to use flowbite components in my project but they are not working , (e.g dropdown, modal,...).
I followed the documentation but nothing works.
I'm using vuejs 3, Vite v2.9.9.
This is my main.js file:
import { createApp } from 'vue'
import App from "#/App.vue";
import router from './router/index'
import store from './state/store'
// Imported css file [TailwindCSS]
import './index.css'
// Imported flowbite
import 'flowbite';
createApp(App)
.use(router)
.use(store)
.mount('#app')
modal.vue
<template>
<!-- Modal toggle -->
<button class="block text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" type="button" data-modal-toggle="default-modal">
Toggle modal
</button>
<!-- Main modal -->
<div id="default-modal" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed right-0 left-0 top-4 z-50 justify-center items-center h-modal md:h-full md:inset-0">
<div class="relative px-4 w-full max-w-2xl h-full md:h-auto">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<!-- Modal header -->
<div class="flex justify-between items-start p-5 rounded-t border-b dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 lg:text-2xl dark:text-white">
Terms of Service
</h3>
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="default-modal">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</button>
</div>
<!-- Modal body -->
test
<!-- Modal footer -->
<div class="flex items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
<button data-modal-toggle="default-modal" type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">I accept</button>
<button data-modal-toggle="default-modal" type="button" class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:ring-gray-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600">Decline</button>
</div>
</div>
</div>
</div>
</template>
I had the same problem at svelte.
I finally solved it:
import 'flowbite/dist/flowbite.js'
...
let modal = new Modal(document.getElementById('modalId'),{placement:'center'})
...
<button on:cllick={()=>modal.show()} >Open</button>
Okay, so what I did to make it work is to create the Modal with Javascript (check here the flowbite documentation) instead of using this data-modal-toggle="defaultModal" property defined in the html component.
Find below an example with Vue3 Single File Component. For other frameworks the solution should be similar.
<template>
<!-- Modal toggle -->
<button class="block text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" type="button" #click="toggleModal">
Toggle modal
</button>
<!-- Main modal -->
<div id="defaultModal" tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full justify-center items-center">
<div class="relative p-4 w-full max-w-2xl h-full md:h-auto">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<!-- Modal header -->
<div class="flex justify-between items-start p-4 rounded-t border-b dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
Terms of Service
</h3>
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" #click="toggleModal">
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<!-- Modal body -->
<div class="p-6 space-y-6">
<p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">
With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.
</p>
<p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">
The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.
</p>
</div>
<!-- Modal footer -->
<div class="flex items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
<button #click="toggleModal" type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">I accept</button>
<button #click="toggleModal" type="button" class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">Decline</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return{
modal: ''
}
},
methods: {
toggleModal() {
this.modal.toggle();
}
},
mounted() {
// set the modal menu element
const targetEl = document.getElementById('defaultModal');
// options with default values
const options = {
placement: 'center',
backdropClasses: 'bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40',
onHide: () => {
console.log('modal is hidden');
},
onShow: () => {
console.log('modal is shown');
},
onToggle: () => {
console.log('modal has been toggled');
}
};
this.modal = new Modal(targetEl, options);
}
}
</script>
This took me 2 weeks to figure out, I am using Vite with Vue.
I followed the instructions here https://flowbite.com/docs/getting-started/vue/
Where it didn't state to add the script tag
<script src="./node_modules/flowbite/dist/flowbite.js"></script>
in my index.html
Which is, stated in #3 https://flowbite.com/docs/getting-started/quickstart/
I tried to position the dropdown to the top of the page using Tailwind CSS and z-index.
But it goes behind of other elements in the grid
image
Code Snipets
<div class="flex flex-col gap-y-4">
<h1 class="text-3xl font-semibold text-left font-display sm:text-4xl">
Following
</h1>
<div class="flex flex-col w-full h-full gap-4 p-4 bg-white border border-gray-200 rounded shadow-md">
<h1 class="mb-3 text-xl font-semibold text-left font-display">
Legislators
</h1>
<div class="flex flex-col items-between">
<div class="relative z-10 grid gap-4 mb-5 xxs:grid-cols-1 xs:grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-3">
<FollowingCard
v-for="govId in legislatorsFollowed"
:key="govId"
class="w-full sm:w-auto"
:legor-id="govId"
/>
</div>
</div>
</div>
FollowingCard.vue
person
{{ name }}
{{ role }} | {{ party }} | {{ state }} of {{ country }} {{showDropdown}}
more_vert
<div v-if="showDropdown" class="absolute top-0 left-0 z-40 flex flex-col py-1 mt-8 overflow-y-auto bg-white border border-gray-200 rounded-md shadow-sm max-h-40" data-testid="sessionDropdownBtn">
<button
v-for="session in topics"
:key="session"
class="relative z-50 flex items-center justify-start w-full px-4 py-2 text-sm text-left capitalize hover:bg-gray-100 font-body min-w-max"
>
{{ session }}
</button>
</div>
</button>
</div>
</transition>
</div>
In my laravel vuejs application I have following vue to display some data inside a datatable .
For the better user experience, I have added a Show more option to load data.
<show-more :data-size="documents.length" increment-amount="5" >
<div slot-scope="{ showMore, showAmount }">
<div v-bind:class = "selectedForAction.count() === 0 ? 'h-15' : ''">
<action-bar :count="selectedForAction.count()">
<div slot="table-header" class="flex items-center justify-between bg-white border-certstyle-border border-b rounded-t py-4 px-10 w-full ">
<!--Course -->
<div class="flex items-center rounded-full w-22 overflow-hidden shadow-soft">
<selectable-all item="selectAll" :data="documents" #select="selectAll"></selectable-all>
</div>
<div class="flex flex-col items-left text-left w-10/12">
Document
</div>
<div class="w-74 text-left" item="validFor">
Valid until
</div>
<div class="w-1/12 text-center" item="status">
Validity
</div>
<div class="px-8 w-32">
</div>
<div class="px-8">
</div>
</div>
<button v-if="selectedForAction.count() === 1" #click="editSelectedDocument" class="flex items-center text-certstyle-titles text-sm mx-4" >
<span class="mr-1">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit-2"><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path></svg>
</span>
<span class="font-bold">Edit</span>
</button>
<button #click="removeSelectedDocument" class="flex items-center text-certstyle-titles text-sm mx-4" >
<span class="mr-1">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x-square"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="9" x2="15" y2="15"></line><line x1="15" y1="9" x2="9" y2="15"></line></svg>
</span>
<span class="font-bold">Remove</span>
</button>
</action-bar>
</div>
<!--Certificates-->
<div v-if="documents[index] !== undefined" v-for="(i, index) in showAmount" class="flex items-center justify-between border-certstyle-border border-b px-10 py-1 hover:bg-certstyle-background-light transition-colors duration-150">
<!--Certificate institute image-->
<div class="flex items-center " item="certificatedChecked" >
<div class="relative">
<div class="rounded-full h-14 w-10 overflow-hidden shadow-soft pt-4">
<selectable
v-model="selectedForAction"
:item="documents[index].id"
:ref="documents[index].id"
></selectable>
</div>
</div>
</div>
<div class="flex flex-col items-left text-left w-10/12" item="certificate">
<span :title="documents[index].name" style="cursor: help;" class="text-certstyle-titles font-bold cursor-help">{{ documents[index].name }}</span>
</div>
<!--Certificate due date-->
<div class="w-74 text-left" item="validFor">
<p class="text-sm valid-until not-applicable" v-if="documents[index].is_valid_forever">{{ 'Indefinite'}}</p>
<p class="text-sm valid-until" v-else>{{ documents[index].expires_at_formatted }}</p>
</div>
<!-- Certificate status-->
<div class="w-48 text-center" item="status">
<status :status="documents[index].validity_status.toLowerCase()"></status>
</div>
<!--Download icon-->
<div class="cs--dashboard-employee-certificate-index--certificate-download-icon px-8" item="download">
<a v-if="documents[index].url !== null" :href="getDocumentDownloadLocation(documents[index].id)" class="text-certstyle-text-light">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
</a>
</div>
<!--Preview icon-->
<div class="cs--dashboard-employee-certificate-index--certificate-download-icon px-8" item="view">
<a v-if="documents[index].url !== null" target="_blank" :href="getDocumentPreviewLocation(documents[index].id)" class="text-certstyle-text-light">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
</a>
</div>
<div class="w-0 flex justify-end">
<edit-documents-modal :document="documents[index]" :identifier="`editDocument${documents[index].id}`"></edit-documents-modal>
</div>
</div>
<div class="relative flex items-center justify-center">
<!--Show more button-->
<button class="absolute border focus:outline-none hover:bg-certstyle-orange bg-white border-certstyle-orange hover:text-white text-certstyle-orange font-bold text-sm rounded px-4 py-1 mt-32 " v-if="showAmount < documents.length" #click="showMore">
show more documents
</button>
</div>
</div>
</show-more>
Now the issue is, When I tried to run this, I get following console error and my data table is not getting displayed. Not even the headers...
[Vue warn]: Error in render: "TypeError: Cannot read properties of
undefined (reading 'length')"
Its better to use computed property to handle these situations
computed: {
getDocumentSize() {
return this.documents ? this.documents.length : 0;
}
}
and in template, do the below change
<show-more :data-size="getDocumentSize" increment-amount="5" >
....