StatsSplit

apps/www/src/sections/StatsSplit.astro · 58 lines · group Stats

StatsSplit — kicker, title, text and the numbers on the left, the picture as a card on the right (<Stat value label detail />).

In the fleet

Not used by any site yet.

Samples 1

sample

THE SEASON SO FAR

What the network noticed this spring

Frost nights arrive earlier and end later than the regional forecast suggests — and they differ between two fields a kilometre apart.

The figures below are the ones growers quote back to us most often.

frost nightsacross the network, March to May
41
between neighbourstypical difference between two nearby fields
2,3 °C
MDX of this sample
<StatsSplit
  kicker="THE SEASON SO FAR"
  title="What the network noticed this spring"
  description={[
    'Frost nights arrive earlier and end later than the regional forecast suggests — and they differ between two fields a kilometre apart.',
    'The figures below are the ones growers quote back to us most often.',
  ]}
  image="photo-02.jpg"
  primaryText="Read the report"
  primaryHref="/report/"
>
  <Stat value="41" label="frost nights" detail="across the network, March to May" />
  <Stat value="2,3 °C" label="between neighbours" detail="typical difference between two nearby fields" />
</StatsSplit>

Props

NameTypeRequiredDefaultDescription
idstring
kickerstring
titlestring
descriptionstring | string[]
themeTheme
imagestring
primaryTextstring
primaryHrefstring
secondaryTextstring
secondaryHrefstring

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

---
/**
 * StatsSplit — kicker, title, text and the numbers on the left, the picture
 * as a card on the right (<Stat value label detail />).
 */
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';
import Section from './_Section.astro';
import type { Theme } from './_Section.astro';
import Button from './_Button.astro';

interface Props {
  id?: string;
  kicker?: string;
  title?: string;
  description?: string | string[];
  theme?: Theme;
  image?: string;
  primaryText?: string;
  primaryHref?: string;
  secondaryText?: string;
  secondaryHref?: string;
}
const p = Astro.props;
const theme = p.theme ?? 'light';
const paragraphs = p.description === undefined ? [] : Array.isArray(p.description) ? p.description : [p.description];
const img = p.image ? await resolveImage(p.image) : undefined;
const primaryHref = p.primaryHref ?? '#';
const secondaryHref = p.secondaryHref ?? '#';
const dark = theme === 'dark' || theme === 'brand';
---

<Section id={p.id} theme={theme}>
  <div class="lg:grid lg:grid-cols-2 lg:items-center lg:gap-16">
    <div>
      {p.kicker && (
        <p class="text-sm font-semibold uppercase tracking-wide">
          <span class="bg-gradient-to-r from-primary-500 to-primary-alt-600 bg-clip-text text-transparent [.bg-stone-800_&]:from-primary-300 [.bg-stone-800_&]:to-primary-alt-400">{p.kicker}</span>
        </p>
      )}
      {p.title && <h2 class="mt-3 text-3xl font-extrabold tracking-tight sm:text-4xl">{p.title}</h2>}
      <div class:list={['mt-6 space-y-4 text-lg', dark ? 'text-gray-300' : 'text-gray-500']}>
        {paragraphs.map((x) => <p>{x}</p>)}
      </div>
      <dl class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-2" data-variant="split">
        <slot />
      </dl>
      {(p.primaryText || p.secondaryText) && (
        <div class="mt-10 flex flex-wrap gap-4">
          {p.primaryText && <Button href={primaryHref}>{p.primaryText}</Button>}
          {p.secondaryText && <Button href={secondaryHref} kind="secondary" onDark={dark}>{p.secondaryText}</Button>}
        </div>
      )}
    </div>
    {img && <Image src={img} alt="" widths={[400, 840]} class="mt-12 w-full rounded-2xl object-cover shadow-xl lg:mt-0" />}
  </div>
</Section>

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.