Skip to content
Bryce Russell edited this page Mar 22, 2023 · 44 revisions

Introduction

npm npm

Astro Headless UI is a collection of headless components and utilities for Astro

Components

This library contains four components types, each type implements a different headless pattern

Style Component

HTML Element with an attached stylesheet

<NoScriptProperty> <AnimatedSpriteSheet> <IconSwitcher>

Component

HTML Element generator, mostly takes advantage of Astro's slot API

<When> <Switch> <For> <Wrap>

<Link> <Navigation> <TableOfContents> <Breadcrumb> <Paginate> <Pagination> <Rating>

Client Component

Interactive HTML Element using vanilla js

<DarkThemeToggle> <MultiThemeToggle> <CodeCopy>

Client Script

A client script that is does not include any HTML

<ScrollProperty> <MouseProperty>

Slots API

Components take advantage of Astro's slots API to give complete control over rendering

Named Slots

Pass an element to a slot using the slot attribute

<Rating total="5" active="2.5">
    <Icon slot="active" name="codicon:star-full"></Icon>
    <Icon slot="half" name="codicon:star-half"></Icon>
    <Icon slot="disabled" name="codicon:star-empty"></Icon>
</Rating>

Slot Functions

Components can pass arguments to slot functions

<Pagination>
  {page => <a href={page.href}>{page.number}</a>}
</Pagination>

Named Slot Functions

To pass a slot function to a named slot the function must be wrapped in a valid HTML element and a slot attribute, this 'wrapper' element does not get rendered in the final output.

<Pagination>
  <active slot="active">
    {page => <a href={page.href}>{page.number}</a>}
  </active>
</Pagination>

Examples

Animated Spritesheet:

Example of a spritehseet being animated Spritesheet being animated in example

<AnimatedSpriteSheet
    url="/boom.png"
    name="boom"
    height={605}
    width={1207}
    cols={8}
    rows={4}
/>

Product Rating:

Example of a star rating for products

---
import { Rating } from 'astro-headless-ui';
import { Icon } from 'astro-icon';
---
<Rating total="5" active="2.5">
    <Icon slot="active" name="codicon:star-full"></Icon>
    <Icon slot="half" name="codicon:star-half"></Icon>
    <Icon slot="disabled" name="codicon:star-empty"></Icon>
</Rating>

Breadcrumb:

Breadcrumb example 1

// "src/pages/posts/categories/javascript/tutorial"
---
import { Breadcrumb } from 'astro-headless-ui';
---
<nav>
    <Breadcrumb />
</nav>

Page navigation:

pagination example

// src/pages/posts/[...page].astro
---
import { Pagination } from 'astro-headless-ui';

export async function getStaticPaths({ paginate }) {
  const posts = await fetch('https://jsonplaceholder.typicode.com/posts').then(response => response.json())
  return paginate(posts , { pageSize: 10 })  
}

const { page } = Astro.props
---

<nav style="display:flex;gap:.25rem;">
  <Pagination index url="/posts" total={page.last} current={page.current}>
    <active slot="active">{page => <span>{page.number}</span>}</active>
    <span slot="disabled">...</span>
    {page => <a href={page.href}>{page.number}</a>}
  </Pagination>
</nav>
<nav style="display:flex;gap:0.25rem;">
    <a href="/posts/">1</a>
    <a href="/posts/2">2</a>
    <span>...</span>
    <a href="/posts/4">4</a>
    <span>5</span>
    <a href="/posts/6">6</a>
    <span>...</span>
    <a href="/posts/9">9</a>
    <a href="/posts/10">10</a>
</nav>