Featurepopular

apps/www/src/sections/Feature.astro · 48 lines · group Features & lists

Feature — one item of <Features>. Icon is an astro-heroicons component imported in the article; image is a file name from images/; number is an ordinal badge; `bullets` a short list; markdown children go under the description. In the aside variant the icon sits to the left of the text.

In the fleet

Used on 4 sites built with this engine.

Samples 1

sampleshown inside <FeatureCards>

WHY NORDVIND

What the station actually changes

  • Frost alerts

    Threshold, rate of fall and dew point, checked every minute inside the crop.

  • Leaf wetness

    Tells you whether the spray will hold before you fill the tank.

  • Offline buffer

    The gateway keeps a week of readings when the uplink drops.

MDX of this sample
import BoltIcon from 'astro-heroicons/outline/Bolt.astro';
import SignalIcon from 'astro-heroicons/outline/Signal.astro';
import CloudIcon from 'astro-heroicons/outline/Cloud.astro';

<FeatureCards kicker="WHY NORDVIND" title="What the station actually changes" columns={3}>
  <Feature title="Frost alerts" description="Threshold, rate of fall and dew point, checked every minute inside the crop." Icon={BoltIcon} />
  <Feature title="Leaf wetness" description="Tells you whether the spray will hold before you fill the tank." Icon={CloudIcon} />
  <Feature title="Offline buffer" description="The gateway keeps a week of readings when the uplink drops." Icon={SignalIcon} />
</FeatureCards>

Props

NameTypeRequiredDefaultDescription
titlestringyes
kickerstring
descriptionstring
Iconany
imagestring
numberstring | number
bulletsstring[][]
linkTextstring
hrefstring

Source apps/www/src/sections/Feature.astro @ gitt.one

---
/**
 * Feature — one item of <Features>. Icon is an astro-heroicons component
 * imported in the article; image is a file name from images/; number is an
 * ordinal badge; `bullets` a short list; markdown children go under the
 * description. In the aside variant the icon sits to the left of the text.
 */
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';
import Button from './_Button.astro';

interface Props {
  title: string;
  kicker?: string;
  description?: string;
  Icon?: any;
  image?: string;
  number?: string | number;
  bullets?: string[];
  linkText?: string;
  href?: string;
}

const { title, kicker, description, Icon, image, number, bullets = [], linkText, href } = Astro.props;
const img = image ? await resolveImage(image) : undefined;
---

<li class="flow-root">
  <div class="flex h-full flex-col rounded-lg px-6 pb-8 pt-8 [ul[data-variant=cards]_&]:bg-gray-50 [ul[data-variant=cards]_&]:text-gray-900 [ul[data-variant=cards]_&]:shadow-sm [ul[data-on-dark]_&]:!bg-white/10 [ul[data-on-dark]_&]:!text-white [ul[data-variant=plain]_&]:px-0 [ul[data-variant=plain]_&]:pt-0 [ul[data-variant=plain]_&]:pb-0 [.bg-stone-800_ul[data-variant=cards]:not([data-on-dark])_&]:bg-white [ul[data-overlap]_&]:relative [ul[data-overlap]_&]:rounded-2xl [ul[data-overlap]_&]:!bg-white [ul[data-overlap]_&]:!text-gray-900 [ul[data-overlap]_&]:!shadow-xl [ul[data-overlap]_&]:!pt-16 [ul[data-overlap]_&]:!pb-8 [ul[data-aside]_&]:grid [ul[data-aside]_&]:grid-cols-[auto_1fr] [ul[data-aside]_&]:gap-x-4">
    {(Icon || number !== undefined) && (
      <span class="inline-flex h-12 w-12 items-center justify-center rounded-md bg-gradient-to-r from-primary-600 to-primary-alt-700 text-xl font-bold text-white shadow-lg [ul[data-icons=soft]_&]:bg-none [ul[data-icons=soft]_&]:bg-primary-50 [ul[data-icons=soft]_&]:text-primary-700 [ul[data-icons=soft]_&]:shadow-none [ul[data-on-dark]_&]:bg-none [ul[data-on-dark]_&]:bg-white/10 [ul[data-on-dark]_&]:text-white [ul[data-overlap]_&]:absolute [ul[data-overlap]_&]:top-0 [ul[data-overlap]_&]:h-16 [ul[data-overlap]_&]:w-16 [ul[data-overlap]_&]:-translate-y-1/2 [ul[data-overlap]_&]:rounded-xl [ul[data-aside]_&]:row-span-2">
        {Icon ? <Icon class="h-6 w-6" aria-hidden="true" /> : number}
      </span>
    )}
    {kicker && <code class="ml-3 rounded bg-white px-2 py-1 font-mono text-sm text-primary-700 ring-1 ring-inset ring-primary-100">{kicker}</code>}
    {img && <Image src={img} alt="" widths={[400, 840]} class="w-full rounded-md" />}
    <h3 class="mt-6 text-lg font-medium tracking-tight [ul[data-variant=cards]_&]:text-primary-800 [ul[data-on-dark]_&]:!text-white [ul[data-aside]_&]:col-start-2 [ul[data-aside]_&]:!mt-0 [ul[data-aside]_&]:leading-6">{title}</h3>
    {description && <p class="mt-3 text-base [ul[data-variant=cards]_&]:text-gray-500 [ul[data-on-dark]_&]:!text-primary-100 [.bg-stone-800_ul[data-variant=plain]_&]:text-gray-300 [ul[data-aside]_&]:col-start-2 [ul[data-aside]_&]:mt-2">{description}</p>}
    {bullets.length > 0 && (
      <ul class="mt-4 list-none space-y-2 text-base text-gray-500 [ul[data-aside]_&]:col-start-2">
        {bullets.map((b) => <li class="flex"><span aria-hidden="true" class="mr-3 mt-2 h-1.5 w-1.5 flex-none rounded-full bg-gradient-to-r from-primary-500 to-primary-alt-600" /><span>{b}</span></li>)}
      </ul>
    )}
    <div class="text-base [ul[data-variant=cards]_&]:text-gray-500 [ul[data-aside]_&]:col-start-2 [&>p]:mt-2"><slot /></div>
    {linkText && href && <p class="mt-auto pt-6 [ul[data-aside]_&]:col-start-2 [ul[data-aside]_&]:!pt-2"><Button href={href} kind="link">{linkText}</Button></p>}
  </div>
</li>

Source links point to engine-astro@38c294d9. Samples are demo content: the components are the real ones, the copy and the pictures are made up.