Coder Social home page Coder Social logo

Comments (27)

sagadsalem avatar sagadsalem commented on May 9, 2024 6

any workaround? for Vue 3 + inertia js

from flowbite.

n-studio avatar n-studio commented on May 9, 2024 5

A simple way would be to encapsulate the event listeners into a public function (let's say Tooltip.start();) and let the user call it in their own listeners.

document.addEventListener("dom-reload", function() {
  Tooltip.start();
});

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024 4

Hey, everyone!

A new standalone Vue 3 library has been started here and @ralphschuler is the maintainer.

If you'd like to help you can contribute to the repository and reach out to me or @ralphschuler :)

https://github.com/themesberg/flowbite-vue

from flowbite.

MilesWuCode avatar MilesWuCode commented on May 9, 2024 3

You're using document.addEventListener('DOMContentLoaded' so it still won't work anytime there is a programmatic change in DOM after initial load (i think). What about cases like using react-router - will all interactive components not work on react router pages? What about initial loading spinners?

I'm either missing something and integrated this wrong, or this still doesn't work for any real life use in react :(

+1 , not working vue-router , only index.vue

vite + vite-plugin-vue-layouts + vite-plugin-pages + vue-router

https://github.com/MilesWuCode/my-vite-template/tree/flowbite

EX:
working
http://localhost:3000

not working
http://localhost:3000/todo

from flowbite.

aleqsio avatar aleqsio commented on May 9, 2024 2

Unfortunately this makes the library unusable in what amounts to i'd wager 80% of modern web applications :/
I'm making a hack like this to make it work, but i'd suggest a more performant solution down the line.

Edited the flowbite.bundle.js with the following addition:

const liveQueries = [];
const container = document.getElementById("root");

const observer = new MutationObserver((records) => {
  liveQueries.forEach((q) => q());
});
observer.observe(container, {
  childList: true,
  subtree: true,
});

const liveQuerySelector = (selector, callback) => {
  const update = () => {
    const found = container.querySelectorAll(selector);
    found.forEach(callback);
  };
  liveQueries.push(update);
};

And replaced each of the 5 top level occurences of
document.querySelectorAll(*some selector*).forEach(function
with
liveQuerySelector(*some selector*, function

It seems that references to elements are still sometimes lost and this might lag on large DOMs, but It's better than nothing.

The code is also up on gist:
https://gist.github.com/aleqsio/6273a99f18ff8f494ca7337d8be7d955

from flowbite.

aleqsio avatar aleqsio commented on May 9, 2024 2

You're using document.addEventListener('DOMContentLoaded' so it still won't work anytime there is a programmatic change in DOM after initial load (i think).
What about cases like using react-router - will all interactive components not work on react router pages?
What about initial loading spinners?

I'm either missing something and integrated this wrong, or this still doesn't work for any real life use in react :(

from flowbite.

alorence avatar alorence commented on May 9, 2024 2

I have this issue too... The main problem is that JS components registration is attached to DOMContentLoaded event. Unfortunately, in some case (very light page content), the DOM finishes to load BEFORE the JS code is executed.

This is very well explained here: https://stackoverflow.com/a/39993724/1887976

A solution would be to transform this kind of code (ex for modal):

document.addEventListener('DOMContentLoaded', () => {
    let modalInstances = []
    document.querySelectorAll('[data-modal-toggle]').forEach(el => {
        const modalId = el.getAttribute('data-modal-toggle');
        const modalEl = document.getElementById(modalId);
        const placement = modalEl.getAttribute('data-modal-placement')

        if (modalEl) {
            if (!modalEl.hasAttribute('aria-hidden') && !modalEl.hasAttribute('aria-modal')) {
                modalEl.setAttribute('aria-hidden', 'true');
            }
        }

        let modal = null
        if (getModalInstance(modalId, modalInstances)) {
            modal = getModalInstance(modalId, modalInstances)
            modal = modal.object
        } else {
            modal = new Modal(modalEl, {
                placement: placement ? placement : Default.placement
            })
            modalInstances.push({
                id: modalId,
                object: modal
            })
        }

        if (modalEl.hasAttribute('data-modal-show') && modalEl.getAttribute('data-modal-show') === 'true') {
            modal.show();
        }

        el.addEventListener('click', () => {
            modal.toggle()
        })
    })
})

into something similar to this

const initModal = () => {
    let modalInstances = []
    document.querySelectorAll('[data-modal-toggle]').forEach(el => {
        const modalId = el.getAttribute('data-modal-toggle');
        const modalEl = document.getElementById(modalId);
        const placement = modalEl.getAttribute('data-modal-placement')

        if (modalEl) {
            if (!modalEl.hasAttribute('aria-hidden') && !modalEl.hasAttribute('aria-modal')) {
                modalEl.setAttribute('aria-hidden', 'true');
            }
        }

        let modal = null
        if (getModalInstance(modalId, modalInstances)) {
            modal = getModalInstance(modalId, modalInstances)
            modal = modal.object
        } else {
            modal = new Modal(modalEl, {
                placement: placement ? placement : Default.placement
            })
            modalInstances.push({
                id: modalId,
                object: modal
            })
        }

        if (modalEl.hasAttribute('data-modal-show') && modalEl.getAttribute('data-modal-show') === 'true') {
            modal.show();
        }

        el.addEventListener('click', () => {
            modal.toggle()
        })
    })
}

if (document.readyState !== 'loading') {
    // DOMContentLoaded event already fired, let's perform initialization explicitely
    initModal()
} else {
    // DOMContentLoaded event not yet fired, attach initialization process to it
    document.addEventListener('DOMContentLoaded', initModal)
}

from flowbite.

Morzaram avatar Morzaram commented on May 9, 2024 1

I'm having the same issue with basic html5 setup (using rails 7)

The dropdown no longer triggers after a page change. I have to refresh the page.

from flowbite.

benoit96 avatar benoit96 commented on May 9, 2024 1

Some context:

<script setup>
import { Link } from '@inertiajs/inertia-vue3'
// import { Dropdown } from 'flowbite'
import Flowbite from 'flowbite'
import { Inertia } from '@inertiajs/inertia'

Inertia.on('finish', () => {
  document.querySelectorAll('[data-dropdown-toggle]').forEach(triggerEl => {
    const targetEl = document.getElementById(triggerEl.getAttribute('data-dropdown-toggle'))
    const placement = triggerEl.getAttribute('data-dropdown-placement')

    Flowbite.Dropdown(targetEl, triggerEl, {
      placement: placement ? placement : 'bottom'
    })
  })
})
</script>

tho seems something is happening in the browser devtools

flowbite__WEBPACK_IMPORTED_MODULE_1___default(...).Dropdown is not a function

You were close to the solution ! Here is what worked for me

<script setup>
import { Link } from '@inertiajs/inertia-vue3'
import Flowbite from 'flowbite'
import { Inertia } from '@inertiajs/inertia'

Inertia.on('finish', () => {
  document.querySelectorAll('[data-dropdown-toggle]').forEach(triggerEl => {
    const targetEl = document.getElementById(triggerEl.getAttribute('data-dropdown-toggle'))
    const placement = triggerEl.getAttribute('data-dropdown-placement')

    const dd = new Dropdown(targetEl, triggerEl, {
      placement: placement ? placement : 'bottom'
    })
  })
})
</script>

1- Dropdown is a class and not a function
2- Looks like when you import the module everything it contains is global so you can use Dropdown directly

I hope this helps !

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024 1

Hey everyone,

So we started working on the Flowbite Vue component library so all Vue and Nuxt-related issues should be addressed there since the main Flowbite Library is based on event listeners and not completely compatible with libraries and frameworks such as React or Vue.js (that's why we started working on actual Vue or React components.)

Feel free to contribute to those repositories!

from flowbite.

radudiaconu0 avatar radudiaconu0 commented on May 9, 2024

i have this issue too on a simple vue 3 project with either vite or webpack

from flowbite.

SalimiHabib avatar SalimiHabib commented on May 9, 2024

same issue in Blazor web assembly
flowbite.bundle.js exist in client side but not working at all

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024

The way the flowbite.bundle.js works is that it looks for the data attributes and then applies event listeners, this means that the JS needs to have an already rendered DOM to make it work.

We are aware of the compatibility issues regarding virtual DOM based libraries and frameworks, we're trying to find solutions.

Please take into account that the other non-interactive components (ie. buttons, alerts, badges) still work regardless of the JS file.

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024

A simple way would be to encapsulate the event listeners into a public function (let's say Tooltip.start();) and let the user call it in their own listeners.

document.addEventListener("dom-reload", function() {

  Tooltip.start();

});

I'll look into this solution tomorrow. Thanks.

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024

Unfortunately this makes the library unusable in what amounts to i'd wager 80% of modern web applications :/

I'm making a hack like this to make it work, but i'd suggest a more performant solution down the line.

Edited the flowbite.bundle.js with the following addition:


const liveQueries = [];

const container = document.getElementById("root");



const observer = new MutationObserver((records) => {

  liveQueries.forEach((q) => q());

});

observer.observe(container, {

  childList: true,

  subtree: true,

});



const liveQuerySelector = (selector, callback) => {

  const update = () => {

    const found = container.querySelectorAll(selector);

    found.forEach(callback);

  };

  liveQueries.push(update);

};

And replaced each of the 5 top level occurences of

document.querySelectorAll(*some selector*).forEach(function

with

liveQuerySelector(*some selector*, function

It seems that references to elements are still sometimes lost and this might lag on large DOMs, but It's better than nothing.

The code is also up on gist:

https://gist.github.com/aleqsio/6273a99f18ff8f494ca7337d8be7d955

Thanks for the workaround and info.

We are looking into a solution to make the event listeners work overall.

We also started a project where we will build separate React and Vue components.

from flowbite.

aleqsio avatar aleqsio commented on May 9, 2024

No worries, thanks for looking into this. Hope there'll be an official solution soon :)
I think even exporting the individual functions as onClick handlers would be a significant step up in functionality while being a hopefully small workload.

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024

With the v1.3.0 release of Flowbite we have now solved the problem of event listeners not registering with front-end libraries and frameworks such as React.js and Vue.

Please check out this guide on how to use Tailwind CSS and Flowbite inside a Vue project.

PS: there's no official Vue package just yet, we're working on that. But interactive elements like tooltips and dropdowns should now work.

from flowbite.

zoltanszogyenyi avatar zoltanszogyenyi commented on May 9, 2024

Hey @aleqsio,

Can you send me a repo to test that out?

Thanks!

PS: we'll launch a standalone React and Vue.js component library at the beginning of Q2, so all of these problems will be solved and you won't need to use the data attributes anymore.

from flowbite.

INFy93 avatar INFy93 commented on May 9, 2024

I also have this problems, but with dropdown elements
Vue 3 + Laravel 8, flowbite 1.3.4
I'm creating table using axios. In one colum I have dropdown with unique "id". But dropdowns isn't work in it.
Outside of element everything works fine.
When im using DaizyUI, dropdowns works. But I have some problems with styling this, so I want use flowbite.
Is any solutions now?..

UPD: Like temporary solution I use dropdowns form Headless UI. This dropdowns work fine

from flowbite.

necony286 avatar necony286 commented on May 9, 2024

Still having this same problem

from flowbite.

knutole avatar knutole commented on May 9, 2024

PS: we'll launch a standalone React and Vue.js component library at the beginning of Q2, so all of these problems will be solved and you won't need to use the data attributes anymore.

@zoltanszogyenyi ETA for Vue.js version?

from flowbite.

col-bc avatar col-bc commented on May 9, 2024

I'm also having problems getting interactive components to work. The setup instructions for vue work, but when vue-rpouter is added to the project, everything stops again.

from flowbite.

ralphschuler avatar ralphschuler commented on May 9, 2024

Same issue here,

when using Vue3 reactivity (v-if) the event listener "breaks" and won't pickup any changes.

I'm using
flowbite: 1.4.7
vue: 3.2.33

from flowbite.

rluders avatar rluders commented on May 9, 2024

Some context:

<script setup>
import { Link } from '@inertiajs/inertia-vue3'
// import { Dropdown } from 'flowbite'
import Flowbite from 'flowbite'
import { Inertia } from '@inertiajs/inertia'

Inertia.on('finish', () => {
  document.querySelectorAll('[data-dropdown-toggle]').forEach(triggerEl => {
    const targetEl = document.getElementById(triggerEl.getAttribute('data-dropdown-toggle'))
    const placement = triggerEl.getAttribute('data-dropdown-placement')

    Flowbite.Dropdown(targetEl, triggerEl, {
      placement: placement ? placement : 'bottom'
    })
  })
})
</script>

tho seems something is happening in the browser devtools

flowbite__WEBPACK_IMPORTED_MODULE_1___default(...).Dropdown is not a function

from flowbite.

rluders avatar rluders commented on May 9, 2024

Nice. The code isn't mine, just bring it from the Discord channel to get some help for a user. Thanks @benoit96

from flowbite.

benoit96 avatar benoit96 commented on May 9, 2024

You're welcome @rluders

from flowbite.

stallyons-developer1 avatar stallyons-developer1 commented on May 9, 2024

Still having the same issue.

from flowbite.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.