← Back

Sibling Count with Astro

It turns out that with Astro things are fairly straight forwards

Steps:

  1. Create a new Astro component. Let us call it `AstroSiblingCount`.

    In this component:

    1. First of all you need a library to parse the html, I am using linkedom
    2. grab the html content you have passed into the component in the default slot
    3. using this html I am selecting it all and creating an array of children
    4. Looping through these children I attach the --sibling-index and --sibling-child inline custom variables.
    ---
    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>
                    `}
                />
            );
        })
    }
  2. 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>