TW-Elements icon indicating copy to clipboard operation
TW-Elements copied to clipboard

[Sveltekit] Components not working properly when updated to 1.0.0-beta2 from 1.0.0-beta1

Open BillyAlbornoz opened this issue 1 year ago โ€ข 24 comments

I updated tailwind elements on my sveltekit project to the new 1.0.0-beta2 version, but the components are not working properly now. In case of textbox, it gives "not read properties of null (reading 'setAttribute')" error, on selects elements the styles are not loading, the dropdowns not working and the datepicker value puts on the placeholder..

To Reproduce Update a sveltekit latest and tailwind elements 1.0.0-beta1 version to tailwind elements 1.0.0-beta2 version

I called all of my elements in the onMount function and all of that are working fine with the 1.0.0-beta1 version

onMount(async () => { te = await import('tw-elements'); const ipAddress = new te.Input(document.getElementById('ipAddress')); });

BillyAlbornoz avatar May 06 '23 02:05 BillyAlbornoz

Hi, with beta2 (changelog here) we added support for ES modules so also changed import methods. Check out Svelte integration tutorial please.

Trochonovitz avatar May 08 '23 11:05 Trochonovitz

Thanks, yes, I followed the tutorial step by step and I made a clean installation of sveltekit and tailwind elements too, but the error remains

BillyAlbornoz avatar May 08 '23 13:05 BillyAlbornoz

Hm, could you provide more informations? Exactly what components generate what errors? Or even better - could you attach here your code?

Trochonovitz avatar May 10 '23 06:05 Trochonovitz

I'm also having an issue with the ES import. My code is failing on importing from 'tw-elements':

6:52:05 PM [vite] Error when evaluating SSR module /src/routes/+layout.svelte: failed to import "tw-elements"
|- ReferenceError: document is not defined
    at st (file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:3074)
    at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:16:20766
    at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:178
    at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:192
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async nodeImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54405:17)
    at async ssrImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54298:24)
    at async eval (/src/routes/+layout.svelte:11:31)

Internal server error: document is not defined
      at st (file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:3074)
      at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:16:20766
      at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:178
      at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:192
      at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
      at async Promise.all (index 0)
      at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
      at async nodeImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54405:17)
      at async ssrImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54298:24)
      at async eval (/src/routes/+layout.svelte:11:31)

The code is fairly simple:

    import { Datepicker, Input, initTE } from 'tw-elements'
    initTE({ Datepicker, Input })

It fails on the import and seems to be SSR related. Has anyone had any luck with the integration tutorial?

Ali-Amir avatar May 13 '23 01:05 Ali-Amir

@Ali-Amir the โ€œdocument is not definedโ€ error happens because you must import tw-elements inside onMount function and assign it to a variable to initialize components, for example:

onMount(async () => { const te = await import('tw-elements'); const a = new te.Input(document.getElementById('a')); // Where โ€œaโ€ is the id of input div to initialize. });

I have never been able to use the components using initTE, it doesnโ€™t work. If you can resolve the problem that I have, please comment here!!

BillyAlbornoz avatar May 13 '23 02:05 BillyAlbornoz

Hi @BillyAlbornoz. Thanks for the quick response. I was able to use the umd style import before and was hoping that the new ES works since it's in the official tutorial. Would still love to hear back from someone who wrote the tutorial or someone who were able to get ES style working.

I'm not too sure about your error but on my side I wrap import with if (browser) (maybe that will help in your case):

import { browser } from '$app/environment'

onMount(async () => {
    if (browser) {
        await import('tw-elements')
    }
})

Ali-Amir avatar May 13 '23 02:05 Ali-Amir

Thanks @Ali-Amir, Iโ€™ll probe it! Do you have tw-elements working properly? What version of sveltekit and tailwind elements are you using?

BillyAlbornoz avatar May 13 '23 02:05 BillyAlbornoz

@BillyAlbornoz Actually, even the old stuff stopped working for me. I was able to get it to work with a hack:

    onMount(async () => {
        if (browser) {
            const te = await import('tw-elements')
            console.log(te.initTE({ Modal: te.Modal }))
        }
    })

Note that it somehow doesn't work without the console.log. Let me know if this works for you.

Hoping to see the "right" way to import though.

Ali-Amir avatar May 13 '23 03:05 Ali-Amir

@Ali-Amir Wow that is weird, and you tried to assign the line inside console log to a variable? In my case to initialize components I had to do that because if It was not assigned into a variable, it doesn't work either, including if the variable was never called

BillyAlbornoz avatar May 13 '23 03:05 BillyAlbornoz

@BillyAlbornoz Good point. ~~Assigning and referencing the variable works~~ (actually, looks like it was a fluke):

const init_result = te.initTE({ Modal: te.Modal })
init_result // This reference is needed

Ali-Amir avatar May 13 '23 03:05 Ali-Amir

I've been able to fix some issues with the components mentioned above, at least the styles now load properly with the latest new version. The solution was to use initTE with the components (with beta1 it worked fine without adding this line). Now the call to my components was as follows:

image

I still have problems when loading the component with data for the first time, but I think it happens more through sveltekit

@Ali-Amir I don't know if you have already solved your problem, but if it helps you, you could review that

BillyAlbornoz avatar May 14 '23 03:05 BillyAlbornoz

Thanks @BillyAlbornoz. This is what I've ended up using. It didn't work consistently when I loaded from +layout.svelte. But once I moved it to a component it started working fine.

Would love to hear back from the authors on what a proper approach would be.

Ali-Amir avatar May 15 '23 16:05 Ali-Amir

I'm also having an issue with the ES import. My code is failing on importing from 'tw-elements':

6:52:05 PM [vite] Error when evaluating SSR module /src/routes/+layout.svelte: failed to import "tw-elements"
|- ReferenceError: document is not defined
    at st (file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:3074)
    at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:16:20766
    at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:178
    at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:192
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async nodeImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54405:17)
    at async ssrImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54298:24)
    at async eval (/src/routes/+layout.svelte:11:31)

Internal server error: document is not defined
      at st (file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:3074)
      at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:16:20766
      at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:178
      at file:///.../dashboard/node_modules/tw-elements/dist/js/tw-elements.umd.min.js:12:192
      at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
      at async Promise.all (index 0)
      at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
      at async nodeImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54405:17)
      at async ssrImport (file:///.../dashboard/node_modules/vite/dist/node/chunks/dep-934dbc7c.js:54298:24)
      at async eval (/src/routes/+layout.svelte:11:31)

The code is fairly simple:

    import { Datepicker, Input, initTE } from 'tw-elements'
    initTE({ Datepicker, Input })

It fails on the import and seems to be SSR related. Has anyone had any luck with the integration tutorial?

I am currently facing the same issues as seen above, by following the svelte integration instructions here.

Reneetjuh21 avatar May 27 '23 19:05 Reneetjuh21

@Reneetjuh21 try the solution that I wrote above, Iโ€™m currently working in that way and everything works perfect.

BillyAlbornoz avatar May 28 '23 17:05 BillyAlbornoz

Hey, is there any update/confirmed solution for this?

May be my lack of knowledge, but I've followed the integration instructions, and tried the other suggestions here but still erroring.

Once I've loaded a client-side DOM for the first time, I'm able to move around the site and use the elements, however upon refreshing the page I get hit with the undefined document error.

Currently I'm using the following in my "modal" .svelte component files:

<script lang="ts">
    import { onMount } from "svelte";
    import { Modal, initTE } from "tw-elements";

    onMount(async () => {
        initTE({ Modal });
    });
</script>

Any ideas?

joshbker avatar Jul 03 '23 01:07 joshbker

Hi @joshbker, I'm using modals like this

import { onMount } from 'svelte';

let te; let modalEditText: any;

onMount(async () => { te = await import('tw-elements'); te.initTE({ Modal: te.Modal }); modalEditText = new te.Modal(document.getElementById('modalEditText')); });

The key is to import tw-elements in onMount life cycle.

BillyAlbornoz avatar Jul 03 '23 01:07 BillyAlbornoz

Hi @joshbker, I'm using modals like this

import { onMount } from 'svelte';

let te; let modalEditText: any;

onMount(async () => { te = await import('tw-elements'); te.initTE({ Modal: te.Modal }); modalEditText = new te.Modal(document.getElementById('modalEditText')); });

The key is to import tw-elements in onMount life cycle.

That makes so much sense as to why I was getting said behaviours.

Thank you, this has solved the issue I was having!


Edit:

In case anyone is interested, I was able to add the below code to my layout, and didn't need to have it in every .svelte file anymore:

import { onMount } from "svelte";
onMount(async () => {
    const te = await import("tw-elements");
    te.initTE({ Modal: te.Modal });
});

joshbker avatar Jul 03 '23 01:07 joshbker

If the official solution to this is to import tw-elements on the client, does that mean there's not plan to support server side rendering?

hugotox avatar Aug 22 '23 17:08 hugotox

@hugotox Yes, we encourage to import the tw-elements components on the client side. There are not (atleast for now) plans to support server side rendering.

juujisai avatar Aug 23 '23 05:08 juujisai

Hi, I tried to use Tailwind-Elements with Electron + Sveltekit and I had problem with components initialized via initTE, which worked well on initial visit - when I revisited same page (I added NavBar with 2 links for different routes), Input components had broken floating labels and it thrown errors '... read properties of null...' I was able to workaround it initializing component via JS. I hope itcan help others and it would be great if initTE was fixed to work in the same way as using querySelectors is kinda ugly :)

szprytny avatar Sep 14 '23 15:09 szprytny

@szprytny Hi, so the issue occurs when changing route / component is mounting and unmounting? In the latest release 1.0.0 we added more options to the initTE method. You can now define whether to allow for reinits or not (I think this may be the issue you are having). Try something like this:

initTE({ Datepicker, Input }, { allowReinits: true });

The initTE method description was also updated on the Quick Start page: https://tailwind-elements.com/docs/standard/getting-started/quick-start/#formats

Let me know if that was the issue or is it something completely different.

juujisai avatar Sep 15 '23 06:09 juujisai

initTE({ Datepicker, Input }, { allowReinits: true });

@juujisai thanks for the reply, that is working as expected now. I don't know if I have something incorrectly configured or if that module does not export type definitions, I would probably find this option myself if IDE was more helpful as I am using typescript lang :)

szprytny avatar Sep 15 '23 15:09 szprytny

@szprytny Does the IDE show an error in some of the modules? We do not export type definitions in TE package. We only declare the tw-elements module.

juujisai avatar Sep 18 '23 05:09 juujisai

@juujisai There are no errors.

szprytny avatar Sep 18 '23 16:09 szprytny