#Getting started with Astro and Shadcn - Dialog component not working.

1 messages · Page 1 of 1 (latest)

topaz crescent
#

I have a fresh Astro install with Shadcn. I installed and imported the Dialog component, and added the example code from their docs in my index.astro file. I'm getting this error:

DialogTrigger must be used within Dialog

I found the same error on a Github issue, but the solution doesn't work for me.
Anyone know what I'm doing wrong?

pliant granite
#

Let me spin it up real quick and see

topaz crescent
#

Getting the same with the Carousel:
useCarousel must be used within a <Carousel />

pliant granite
#

I got it working.

topaz crescent
#

Awesome. How?

pliant granite
#

I creted a "DialogWrapper" react component and then passed that into Astro with a Client Directive. Its kinda Janky but it works. One sec and I can grab you the github repo

topaz crescent
#

I saw a similar approach on a Github issue, but I wanted to avoid it

pliant granite
topaz crescent
#

Sure. Thanks for checking.

pliant granite
#

Thats the only way to do it.

topaz crescent
#

oof that sucks

#

I'd have to add all the necessary props manually so it works as intended

pliant granite
#

What do you mean?

topaz crescent
#

oh scratch that, I need to test before I talk lol

pliant granite
#

One sec and il push up some changes that repo with more components

topaz crescent
#

It doesn't happen for all the components by the way. The <Button> for example works out of the box

#

There was a user on GH that solved it by using client:load but that won't work for me

#

Is it a hydration issue though?

topaz crescent
#

yep, that's what I meant

pliant granite
#

Pushed some more componets the repo. So just check it out

topaz crescent
#

yeah I get it

#

just need to add wrappers

pliant granite
#

Yup. So astro can hydrate them

topaz crescent
#

why can't it hydrate when using them directly on a page?

pliant granite
#

Oh like this?

        <Dialog client:load>
            <DialogTrigger client:load>Open</DialogTrigger>
            <DialogContent client:load>
                <DialogHeader client:load>
                    <DialogTitle client:load>Are you absolutely sure?</DialogTitle>
                    <DialogDescription client:load>
                        This action cannot be undone. This will permanently
                        delete your account and remove your data from our
                        servers.
                    </DialogDescription>
                </DialogHeader>
            </DialogContent>
        </Dialog>
#

Or something else?

topaz crescent
#

yeah for example

#

without wrapping in another file

#

I tried that exact same thing but it didn't work

pliant granite
#

Probably has to do with how Astro hydrates those under the hood. But im not fully sure. Anyone <@&1129102257422610512> have an idea on this ?

gloomy knot
pliant granite
#

So the approach I shared originally.

marble linden
#

If you are sharing state you could use nano stores too

abstract hearth
#

Each React component used in an Astro component is hydrated as an entirely independed React app.
So things like a provider (used by Shadcn) won't work across them since they don't share the same React instance under the hood, it's two independent React apps communicating through their properties

#

That is why Astro supports a Svelte island inside a React island inside a Solid island

#

They are all independent apps that behave as a black box for the one above

topaz crescent
#

If I have to create a wrapper (if that's the correct term), then I can't edit the component directly. So it would be inconvenient to use.

I'd have to basically re-create the component and pass props to the wrapper, and the wrapper then passes those props to the component.

#

Example:

I want to use the Dialog component.

npx shadcn@latest add dialog

Now I have a dialog.tsx file in components/ui/ which I can't use directly.

So I create Dialog.astro with the content:

---
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
---

<Dialog>
  <DialogTrigger>Open</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Are you absolutely sure?</DialogTitle>
      <DialogDescription>
        This action cannot be undone. This will permanently delete your account
        and remove your data from our servers.
      </DialogDescription>
    </DialogHeader>
  </DialogContent>
</Dialog>
#

But I'd have to edit this file each time I want to re-use it with different content.

#

So for each shadcn component, I have to create a astro file and create props and pass it to the tsx file, which then passes it to the actual component

#

Some components have a lot of props. The Button for example has 7.

pliant granite
#

You dont need create a Dialog.astro file.

livid token
#

Here’s a direct to your example hunter

pliant granite
#

Yeah I just linked the whole example lol

livid token
#

But it’s essentially the same

#

Is there an advantage to using .tsx

pliant granite
#

Have to use .tsx since it contains jsx

topaz crescent
#

Yeah, you're just using a tsx file instead of astro, but the point remains, no?

#

I still have to create props for all the options

pliant granite
#

By using a .tsx file. You are creating 1 "Island" for the entire "Dialog".

livid token
#

Oh right yeah

#

But f3bs point about making it generic is good

#

It’s a pain

pliant granite
livid token
#

Not sure what we can do

#

Maybe PR to shadcn to add generic ones for Astro itself

pliant granite
#

Can you not pass in props to Astro Islands ?

#

No you can.

#

@topaz crescent Which component are you trying to use?

livid token
#

You can it’s just a pain

#

to make all those props etc

topaz crescent
#

I'm playing around with Shadcn for the first time. I'm not actually building anything. But I tried to use the Dialog, AlertDialog and Carousel for example. And all give the same erroras I stated in my first post

topaz crescent
#

I'm making a component based on a component. I have to create props, so they can be passed to the other component's props.

#

And that for perhaps every shadcn component?

pliant granite
#

Only the Interactive ones.

livid token
#

yeah all of them

#

But we can’t really do anything about it that I’m aware of

#

Except have shadcn make them for us

#

Which they might accept a PR for idk

topaz crescent
#

Yeah, or have AI create the 'wrappers' lol

livid token
#

Haha

#

We could make our own component library and distribute that separately

#

They’re really not that painful

#

Adam did that with Astro shoelace

#

I mean not that painful to make once

#

Having to make for every project is annoying

pliant granite
#

It would be possible.

#

Thats a big undertaking lol

#

Would be down to help. But definitely can’t do it by myself

topaz crescent
#

Me too, though I'm an amateur when it comes to js(x)/ts(x). Definitely would like to help out.

native marsh
#

I know a ton of people would love this. Don't know anything about shad or react, but if it's just a wrapper like Astrolace it'd be awesome

marble linden
#

Just rebuild all the shadCN components in astro

#

and release a new lib

#

Houstcn

livid token
#

So we’d start by getting a list of the interactive components that need wrappers

#

Also it could just be that we put them online for people to copy paste instead of attempting to distribute them through npm

#

I might play around with it tonight if I have time and I’ll throw it in this chat if I get all the props etc

pliant granite
#

Ill play around with it here now and see

marble linden
#

Id be down to help, feel free to add me if a repo gets made

Also it could just be that we put them online for people to copy paste instead of attempting to distribute them through npm

I kinda like this, feels very in keeping with the original haha

#

Honestly why stop there

astro-wrappers.com
Let’s go

#

KuiperBeltUI

pliant granite
#

Its available.

marble linden
#

"Custom Astro component wrappers for all your favorite UI libraries!"

red merlin
marble linden
#

idk if anyone actually bought it lol

red merlin