Skip to main content
Feature blocks display a grid of capability tiles — each tile typically has an icon, a title, a short description, and an optional link. All 6 variants use the same flat-props interface and share the SectionGrid + Tile primitive composition.

Variants

features-1

Three-column icon tile grid with section heading, description prose, and two CTA buttons above the grid.

features-2

Two-column card grid with larger tiles and more prominent imagery.

features-3

Single-column list layout: icon tiles stacked vertically for scannable feature lists.

features-4

Four-column compact icon grid, suited for dense feature comparisons.

features-5

Three-column grid with numbered tiles instead of icons.

features-6

Alternating icon tile layout with section prose interspersed between rows.

Sanity _type names

features-1.astro  →  _type: "features-1"
features-2.astro  →  _type: "features-2"
...through features-6

Props interface

features-1.astro is the canonical reference for all feature block variants:
// astro-app/src/components/blocks/features-1.astro
interface Props {
  class?: string
  id?: string
  links?: {
    icon?: string
    text?: string
    href?: string
    target?: string
  }[]
  items?: {
    title?: string
    description?: string
    icon?: string
    href?: string
    links?: {
      icon?: string
      text?: string
      href?: string
      target?: string
    }[]
  }[]
}
class
string
Additional CSS classes forwarded to the root <Section> element.
id
string
HTML id attribute for anchor navigation.
Section-level CTA buttons rendered above the grid. First item uses default variant, remaining use outline. Each item accepts icon, text, href, and target.
items
object[]
Array of feature tiles. Each tile accepts:
  • title — tile heading text
  • description — supporting copy
  • icon — Lucide or Iconify icon name (e.g. "zap", "shield", "settings")
  • href — makes the entire tile a link
  • links — per-tile inline link buttons rendered in TileActions
Section heading and prose copy are passed through the default <slot />.

Storybook story

// astro-app/src/components/blocks/features-1.stories.ts
export const Default = {
  args: {
    links: [
      { text: "Get Started", href: "#" },
      { text: "Learn More", href: "#" }
    ],
    items: [
      {
        icon: "zap",
        title: "Lightning Fast",
        description: "Built for speed and performance.",
        href: "#"
      },
      {
        icon: "shield",
        title: "Secure by Default",
        description: "Enterprise-grade security built in.",
        href: "#"
      },
      {
        icon: "settings",
        title: "Customizable",
        description: "Tailor everything to your needs.",
        href: "#"
      }
    ]
  }
}
Icons are resolved by the @iconify/utils package from the @iconify-json/lucide set. Any Lucide icon slug works as the icon value.

Component internals

Internally, features-1.astro composes fulldev/ui primitives:
<Section>
  <SectionContent>
    <SectionProse><slot /></SectionProse>
    <SectionActions>{/* links[] → Button variants */}</SectionActions>
  </SectionContent>
  <SectionGrid>
    {items?.map(({ title, description, icon, links }) => (
      <Tile>
        <TileMedia variant="icon"><Icon name={icon} /></TileMedia>
        <TileContent>
          <TileTitle>{title}</TileTitle>
          <TileDescription>{description}</TileDescription>
        </TileContent>
        <TileActions>{/* per-tile links[] */}</TileActions>
      </Tile>
    ))}
  </SectionGrid>
</Section>

Installation

npx shadcn@latest add @fulldev/features-1
Repeat for each variant (features-2 through features-6) as needed.
All 6 features variants are pre-installed in the repo. Sanity schema wiring is tracked in Stories 2.4–2.8.

Build docs developers (and LLMs) love