How to solve flowbite modal problem in vue js - vue.js

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.

Related

I'm trying to use Dialog headless ui as a way to open a modal out of my dropdown, but everything I've tried so far hasn't worked

Apologies as I'm new to headless ui and vue in general. I have a dropdown in my parent component that works. What I'm trying to do is use dialog to open a modal upon clicking the button in the dropdown. The issue is everyway I have thought to try either causes the dropdown to flash open and close, or the dropdown to open, allow me to click the modal button, but nothing happens, no modal appears. Below is my code for the dialog modal:
<template>
<div class="flex items-center justify-center">
<button type="button" #click="openModal" class="rounded-md bg-black bg-opacity-20 px-4 py-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
Open dialog
</button>
</div>
<TransitionRoot appear :show="isOpen" as="template">
<Dialog as="div" #close="closeModal" class="relative">
<TransitionChild as="template" enter="duration-300 ease-out" enter-from="opacity-0" enter-to="opacity-100" leave="duration-200 ease-in" leave-from="opacity-100" leave to="opacity-0">
<div class="fixed inset-0 bg-black bg-opacity-25" />
</TransitionChild>
<div class="fixed inset-0 overflow-y-auto">
<div
class="flex min-h-full items-center justify-center p-4 text-center"
>
<TransitionChild as="template" enter="duration-300 ease-out" enter-from="opacity-0 scale-95" enter-to="opacity-100 scale-100" leave="duration-200 ease-in" leave-from="opacity-100 scale-100" leave-to="opacity-0 scale-95">
<DialogPanel
class="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all"
>
<DialogTitle
as="h3"
class="text-lg font-medium leading-6 text-gray-900"
>
Payment successful
</DialogTitle>
<div class="mt-2">
<p class="text-sm text-gray-500">
Your payment has been successfully submitted. We’ve sent you
an email with all of the details of your order.
</p>
</div>
<div class="mt-4">
<button
type="button"
class="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
#click="closeModal"
>
Got it, thanks!
</button>
</div>
</DialogPanel>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</template>
<script setup>
import { ref } from 'vue'
import {
TransitionRoot,
TransitionChild,
Dialog,
DialogPanel,
DialogTitle,
} from '#headlessui/vue'
const isOpen = ref(true)
function closeModal() {
isOpen.value = false
}
function openModal() {
isOpen.value = true
}
</script>

Flowbite plugin not working in RouterView

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

Flowbite modal not showing

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/

How to position the dropdown to top of the grid elements

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>

Vue2-medium editor styles not pulling in

I'm trying to work with this vue2-medium-editor based on this: https://github.com/FranzSkuffka/vue-medium-editor
I'm following the instructions but Im not getting the styles to load for some reason..
So, my first step I installed
yarn add vue2-medium-editor
Then I imported my component in:
<template>
<div class="flex flex-col h-screen">
<div class="grid place-items-center">
<!-- Auth Card -->
<div
class="w-full p-12 px-6 sm:px-10 bg-white rounded-lg shadow-md lg:shadow-lg"
>
<!-- <h2
class="text-center font-semibold text-3xl lg:text-4xl text-gray-800"
>
</h2> -->
<form method="POST">
<!-- Email Input -->
<input
id="title"
type="text"
name="title"
placeholder="Title of your story"
class="text-xl block w-full py-5 px-2 mt-2 text-gray-800 appearance-none border-b-2 border-gray-100 focus:text-gray-500 focus:outline-none focus:border-gray-200"
required
/>
<editor :content='content' :options='options'></editor>
</form>
<div class="mt-5 flex justify-between">
<router-link :to="{ name: 'write-story' }">
<button class="bg-transparent hover:bg-blue-500 text-blue-700 font-bold py-2 px-4 rounded inline-flex items-center border-2 border-blue-500 hover:text-white hover:border-transparent">
<svg class="ml-2 fill-current w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z"/></svg>
<span>Back</span>
</button>
</router-link>
<router-link :to="{ name: 'home' }">
<button class="bg-transparent hover:bg-blue-500 text-blue-700 font-bold py-2 px-4 rounded inline-flex items-center border-2 border-blue-500 hover:text-white hover:border-transparent">
<span>Submit</span>
</button>
</router-link>
</div>
</div>
</div>
</div>
</template>
<script>
import editor from 'vue2-medium-editor'
export default {
name: "new-question",
components: { editor },
data() {
return {
content: "test",
options: {
}
}
}
}
</script>
Theres a step in the documentation to include the required css and it points to the css on the base medium editor.
So, I installed medium editor with yarn add medium-editor
Then I included the styles like this based on this github repo: https://github.com/tui2tone/vue2-medium-editor =>
<style>
#import "~/medium-editor/dist/css/medium-editor.css";
#import "~/vue2-medium-editor/src/themes/default.css";
</style>
This is within the same file. It bult successfully but it doesnt seem to work.
This is what Im getting now:
What am I missing?
Edit 1
if I do this:
<style>
#import "medium-editor/dist/css/medium-editor.css";
#import "vue2-medium-editor/src/themes/default.css";
</style>
I get this error:
Uncaught Error: Cannot find module '-!../../../../node_modules/css-loader/index.js??ref--6-1!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!./medium-editor/dist/css/medium-editor.css'
at webpackMissingModule (app.js:3172)
at Object../node_modules/css-loader/index.js?!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/containers/Story/Create.vue?vue&type=style&index=0&lang=css& (app.js:3172)
at __webpack_require__ (app.js:20)
at Object../node_modules/style-loader/index.js!./node_modules/css-loader/index.js?!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/containers/Story/Create.vue?vue&type=style&index=0&lang=css& (app.js:21655)
at __webpack_require__ (app.js:20)
at Module../resources/js/containers/Story/Create.vue?vue&type=style&index=0&lang=css& (app.js:61170)
at __webpack_require__ (app.js:20)
at Module../resources/js/containers/Story/Create.vue (app.js:61119)
at __webpack_require__ (app.js:20)
at Module../resources/js/router.js (app.js:61283)
```