Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 BUG: Can't pass astro template to component as a prop. #3964

Closed
1 task
thetarnav opened this issue Jul 18, 2022 · 5 comments
Closed
1 task

🐛 BUG: Can't pass astro template to component as a prop. #3964

thetarnav opened this issue Jul 18, 2022 · 5 comments

Comments

@thetarnav
Copy link

thetarnav commented Jul 18, 2022

What version of astro are you using?

1.0.0-beta.72

Are you using an SSR adapter? If so, which one?

doesn't apply

What package manager are you using?

pnpm

What operating system are you using?

Windows 10

Describe the Bug

Astro template can't be passed to an island component property, but it can be passed as children.
This could cause a weird situation where I'm not able to set a certain prop in the .astro files, and I have to create a .tsx wrapper, only to be able to pass jsx to an island.
But such a workaround prevents the ability to granularly set, or not set the client: directives. You can only control the wrapper hydration.

I'm using Solid, but I guess this applies to any framework as it's the compiler issue.

This is probably a known issue, but I'm just curious if this is something that could be fixed in the future.

// Solid component
const Post = props => {
   return (
      <>
         <h1>{props.header}</h1>
         <main>{props.children}</main>
         <footer>{props.footer}</footer>
      </>
   )
}

// Astro component
<Post
   header={<span>this won't work</span>}
   footer={<SomeOtherCompoenent/>}
>
   <p>this works fine</p>
</Post>

image

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-at2rbu?file=src%2Fpages%2Findex.astro

Participation

  • I am willing to submit a pull request for this issue.
@natemoo-re
Copy link
Member

Thanks for opening an issue! This is an intentional limitation of our compiler, though I'm sure we could provide a better error message here.

Instead of passing elements in as props, you should pass the elements as children and use the slot attribute. For JSX frameworks, each of these slots will be passed in as a prop.

<Post>
  <span slot="header">this is passed as `header`</span>
  <p>this works fine</p>
  <SomeOtherCompoenent slot="footer" />
</Post>

https://stackblitz.com/edit/github-at2rbu-9xff7k?file=src%2Fpages%2Findex.astro

@natemoo-re natemoo-re closed this as not planned Won't fix, can't repro, duplicate, stale Jul 19, 2022
@thetarnav
Copy link
Author

Oh nice, I had no idea that slots worked this way.
Thanks for the answer :)

@clarkmcc
Copy link

Maybe I need to open a new issue for this, but how can I pass a component to a React component in an Astro template? In other words, I have an Astro component that includes a React component, and I'd like to pass some custom component into that React component, but from within the Astro component. I can't use slots right because the React component is where my custom component is going to be rendered.

@gar1t
Copy link

gar1t commented Apr 24, 2024

I would not make this behavior intentional, but rather a concede that the parser is incomplete.

Properties are both typed and non-opaque values, whereas slots - unless I'm missing something - provide outlets to pass content through opaquely.

Here's a simple case.

---
interface Props {
  items: HTMLElement[];
}
const { items } = Astro.props;
---
{ items.map(item => <div class="wrapped">{item}</div>) }

To not support this intentionaly is surprising.

@kidonng
Copy link
Contributor

kidonng commented Nov 27, 2024

Pardon for necro-bumping, but here's a more detailed explanation from the maintainers, for those interested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants