---
title: "Reference"
---

import { getFolder } from '../../lib/content';
import FinderLink from '../../components/FinderLink.astro';

export const folder = await getFolder('reference');

export const CORE_ATTRIBUTES = ['hx-get', 'hx-post', 'hx-put', 'hx-patch', 'hx-delete', 'hx-swap', 'hx-target', 'hx-trigger', 'hx-select', 'hx-on', 'hx-vals'];
export const REQUEST_HEADERS = ['HX-Request', 'HX-Request-Type', 'HX-Current-URL', 'HX-Source', 'HX-Target', 'HX-Boosted', 'HX-History-Restore-Request', 'Accept', 'Last-Event-ID'];

export const groups = folder.folders.map(sub => {
    const items = sub.files.map(f => ({
        title: f.frontmatter.title,
        url: f.url,
        description: f.frontmatter.description,
    }));

    if (sub.slug === 'attributes') {
        const core = items.filter(i => CORE_ATTRIBUTES.includes(i.title));
        const additional = items.filter(i => !CORE_ATTRIBUTES.includes(i.title));
        return { slug: sub.slug, label: sub.frontmatter.title, subgroups: [
            { label: 'Core', items: core },
            { label: 'Additional', items: additional },
        ]};
    }
    if (sub.slug === 'headers') {
        const request = items.filter(i => REQUEST_HEADERS.includes(i.title));
        const response = items.filter(i => !REQUEST_HEADERS.includes(i.title));
        return { slug: sub.slug, label: sub.frontmatter.title, subgroups: [
            { label: 'Request', items: request },
            { label: 'Response', items: response },
        ]};
    }
    return { slug: sub.slug, label: sub.frontmatter.title, subgroups: [{ label: null, items }] };
});

<nav class="not-prose">
    <input
        id="filter-input"
        type="text"
        placeholder="Filter reference..."
        autocomplete="off"
        class="w-full px-3 py-2 mb-2 text-sm border border-neutral-200 dark:border-neutral-800 rounded-md bg-white dark:bg-neutral-900 text-neutral-800 dark:text-neutral-200 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 focus:outline-none focus:ring-2 focus:ring-neutral-300/50 dark:focus:ring-neutral-600/50 focus:border-neutral-300 dark:focus:border-neutral-600"
        _="on input
            set q to my.value.toLowerCase()
            if q is ''
                for s in <.filter-group/> remove @hidden from s end
                for sg in <.filter-subgroup/> remove @hidden from sg end
                for i in <.filter-item/> remove @hidden from i end
                for ct in <.filter-count/>
                    set parts to ct.dataset.total
                    put parts into ct
                end
            else
                for section in <.filter-group/>
                    set sectionTotal to 0
                    for subgroup in <.filter-subgroup/> in section
                        set subgroupTotal to 0
                        for item in <.filter-item/> in subgroup
                            if item.dataset.filter contains q
                                remove @hidden from item
                                increment subgroupTotal
                            else
                                add @hidden to item
                            end
                        end
                        set sectionTotal to sectionTotal + subgroupTotal
                        if subgroupTotal is 0 then add @hidden to subgroup else remove @hidden from subgroup
                    end
                    put sectionTotal into first <.filter-count/> in section
                    if sectionTotal is 0 then add @hidden to section else remove @hidden from section
                end
            end"
    />
    {groups.map(group => {
        const totalItems = group.subgroups.reduce((n, sg) => n + sg.items.length, 0);
        return (
            <section class="filter-group mt-8">
                <h2 id={group.slug} class="flex items-baseline gap-2.5 mb-3 scroll-mt-[calc(var(--header-height)+var(--construction-banner-height,0px)+2rem)]">
                    <a href={`#${group.slug}`} class="text-base font-semibold text-neutral-800 dark:text-neutral-100 no-underline interact:underline">
                        {group.label}
                    </a>
                    <span class="filter-count text-xs font-normal text-neutral-400 dark:text-neutral-500 tabular-nums" data-total={totalItems}>{totalItems}</span>
                </h2>
                {group.subgroups.map((sg, si) => (
                    <div class="filter-subgroup">
                        {sg.label && (
                            <h3 id={`${group.slug}-${sg.label.toLowerCase()}`} class="font-sans text-xs font-medium uppercase tracking-widest text-neutral-600 dark:text-neutral-400 mt-6 mb-2 scroll-mt-[calc(var(--header-height)+var(--construction-banner-height,0px)+2rem)]">
                                {sg.label}
                            </h3>
                        )}
                        <div class="grid grid-cols-[auto_1fr] gap-0.5">
                            {sg.items.map(item => (
                                <FinderLink href={item.url} class="filter-item col-span-2 grid grid-cols-subgrid gap-5 items-center" data-filter={`${item.title} ${item.description || ''}`.toLowerCase()}>
                                    <span class="font-mono text-sm font-medium">{item.title}</span>
                                    {item.description ? (
                                        <span class="text-sm text-neutral-650 dark:text-neutral-350 group-interact/link:text-white dark:group-interact/link:text-black transition">{item.description}</span>
                                    ) : <span />}
                                </FinderLink>
                            ))}
                        </div>
                    </div>
                ))}
            </section>
        );
    })}
</nav>
