Code Monkey home page Code Monkey logo

Comments (7)

sarah11918 avatar sarah11918 commented on August 23, 2024 1

Thanks for creating this issue! Is @BryceRussell 's comment on Discord relevant to capture here, too? https://discord.com/channels/830184174198718474/872579324446928896/1263701298591698954

When passing functions to named slots, does not work, it has to be a html tag that does not contain a - like: , or , etc

<YourAstroComponent>
  <fragment slot="with-options">
    {() => ...}
  </fragment>
</YourAstroComponent>

Issue: withastro/astro#6683

from docs.

Soviut avatar Soviut commented on August 23, 2024

I originally asked about this because I use Vue's "scoped slots" a lot. https://vuejs.org/guide/components/slots.html#scoped-slots

It would be great if this pattern was given its own sub-section and named "Scoped slots". While the approach from Vue is very different, it would at least convey the intent.

from docs.

Soviut avatar Soviut commented on August 23, 2024

For context, here's what I was demonstrating with Vue in the Discord

in the long term what i'm hoping for is this (note: Vue syntax)

MyList.vue (component)

<script setup lang="ts">
defineProps<{
  items: string[]
}>()
</script>

<template>
  <ul>
    <li v-for="(item, index) in items">
      <slot :item="item" :index="index" :total="items.length" />
    </li>
  </ul>
</template>

Index.vue (usage)

<MyList :items="items" v-slot="{ item, index, total }">
  <div>
    {{item}}
    <span>( {{index}} / {{total}} )</span>
  </div>
</MyList>

Note how the v-slot yields not only the item but also additional context like the index and total from within the component.

Here is a slightly modified Stackblitz that @Fryuni sent to me that does the same thing in Astro
https://stackblitz.com/edit/github-oqp5kf-ozddjd?file=src%2Fcomponents%2FMyList.astro,src%2Fpages%2Findex.astro

---
const { items } = Astro.props;
---
<ul>
  {items.map((item, index, list) => (
    <li set:html={Astro.slots.render('default', [item, index, list])} />
  ))}
</ul>
<MyList items={numbers}>
  {(item, index, list) => (
    <>
      Item {index}:
      <ul>
        <li>Value: {item}</li>
        <li>Last occurrence: {list.lastIndexOf(item)}</li>
      </ul>
    </>
  )}
</MyList>

While I prefer the Vue syntax, this makes it clear that scoped slots are possible.

from docs.

BryceRussell avatar BryceRussell commented on August 23, 2024

I think it would be great to document named slot functions, but it will be tricky.

The default assumption user's have when passing named slot functions is to use a <Fragment>:

<Component>
	<Fragment slot="one">
		{() => ...}
	</Fragment>
</Component>

But due to the way Astro renders components/slots this is not possible. Instead, users have to use a HTML tag to pass the function to a slot:

<Component>
	<fragment slot="one">
		{() => ...}
	</fragment>
</Component>

But this syntax some issues because it feels hacky:

  • The wrapping HTML tag does NOT get rendered, it is only used to pass the function to a slot. This is confusing because it is the only case where an HTML tag inside a file does not get included in the final output.
  • The HTML tag name is arbitrary, which can be confusing because examples that do the same thing can look very different (see example below)
  • The tag name cannot be slot or include a dash - (like you would typically use for web components)
// These example do the same thing but the last 3 examples are less explicit and more confusing than the first

<Component>
	<fragment slot="one">
		{() => ...}
	</fragment>
</Component>

<Component>
	<f slot="one">
		{() => ...}
	</f>
</Component>

<Component>
	<one slot="one">
		{() => ...}
	</one>
</Component>

<Component>
	<div slot="one">
		{() => ...}
	</div>
</Component>

from docs.

sarah11918 avatar sarah11918 commented on August 23, 2024

Thanks Bryce! While maybe not "quick" to document, you've laid out the pattern very well in a way that makes sense and I do think we could get that into docs.

@Soviut if you had seen documentation like Bryce's post above, would that have answered your original question, and would you have been able to work from that?

from docs.

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.