It turns out that with Astro things are fairly straight forwards
Steps:
Create a new Astro component. Let us call it `AstroSiblingCount`.
In this component:
---
import { parseHTML } from "linkedom";
const html = await Astro.slots.render("default");
const { document } = parseHTML(html);
const [...children] = document.children;
const siblingCount = children.length;
---
{
children?.map((htmlString, index) => {
const siblingIndex = index + 1;
return (
<Fragment
set:html={`
<li style="--sibling-index: ${siblingIndex}; --sibling-count: ${siblingCount};">
${htmlString.textContent}
</li>
`}
/>
);
})
}Use the component:
<ul class="demo">
<AstroSiblingCount>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</AstroSiblingCount>
</ul>
Would yield:
<ul class="demo">
<li style="--sibling-index: 1; --sibling-count: 5;"></li>
<li style="--sibling-index: 2; --sibling-count: 5;></li>
<li style="--sibling-index: 3; --sibling-count: 5;></li>
<li style="--sibling-index: 4; --sibling-count: 5;></li>
<li style="--sibling-index: 5; --sibling-count: 5;></li>
</ul>