CompareItempopular
apps/www/src/sections/CompareItem.astro · 55 lines · group Compare
CompareItem — one side of a <Compare>: a card with a picture, a code sample (`code` + `file`), an icon, bullets, and markdown children. *emphasis* inside `description` strings is painted in the brand color (the convention inherited from the older sites).
In the fleet
Used on 3 sites built with this engine.
Samples 1
<Compare>TWO WAYS TO RUN IT
Cloud or your own server
The stations do not care; the data can live where your policy says it should.

Nordvind Cloud
We keep the servers, the backups and the forecasts up to date.
- Nothing to install
- Forecasts included
- Updates on the day they ship

On your own server
The same software inside your network, on your hardware.
- Data never leaves the farm
- Your backup policy
- Yearly licence
MDX of this sample
<Compare columns={2} kicker="TWO WAYS TO RUN IT" title="Cloud or your own server" description="The stations do not care; the data can live where your policy says it should.">
<CompareItem title="Nordvind Cloud" description="We keep the servers, the backups and the forecasts up to date." bullets={['Nothing to install', 'Forecasts included', 'Updates on the day they ship']} image="screen-01.png" />
<CompareItem title="On your own server" description="The same software inside your network, on your hardware." bullets={['Data never leaves the farm', 'Your backup policy', 'Yearly licence']} image="screen-02.png" />
</Compare>Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| title | string | yes | ||
| kicker | string | |||
| description | string | string[] | |||
| image | string | |||
| Icon | any | |||
| bullets | string[] | [] | ||
| code | string | |||
| file | string |
Source apps/www/src/sections/CompareItem.astro @ gitt.one
---
/**
* CompareItem — one side of a <Compare>: a card with a picture, a code
* sample (`code` + `file`), an icon, bullets, and markdown children.
* *emphasis* inside `description` strings is painted in the brand color
* (the convention inherited from the older sites).
*/
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';
interface Props {
title: string;
kicker?: string;
description?: string | string[];
image?: string;
Icon?: any;
bullets?: string[];
code?: string;
file?: string;
}
const { title, kicker, description, image, Icon, bullets = [], code, file } = Astro.props;
const img = image ? await resolveImage(image) : undefined;
const paragraphs = description === undefined ? [] : Array.isArray(description) ? description : [description];
---
<div class="flex flex-col overflow-hidden rounded-lg bg-white text-gray-900 shadow-lg">
{img && <Image src={img} alt={title} widths={[400, 840]} class="h-48 w-full max-w-full flex-shrink-0 object-contain" />}
<div class="flex flex-1 flex-col p-6">
<div class="flex items-center gap-3">
{Icon && <span class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-md bg-gradient-to-r from-primary-500 to-primary-alt-600"><Icon class="h-5 w-5 text-white" aria-hidden="true" /></span>}
{kicker && <code class="rounded bg-gray-50 px-2 py-1 font-mono text-sm text-primary-700 ring-1 ring-inset ring-primary-100">{kicker}</code>}
</div>
<h3 class:list={['text-xl font-semibold', (Icon || kicker) && 'mt-4']}>{title}</h3>
{paragraphs.length > 0 && (
<div class="mt-3 text-base text-gray-500">
{paragraphs.map((p) => (
<p class="my-2">{p.split('*').map((chunk, i) => <span class:list={[i % 2 === 1 && 'text-primary-600']}>{chunk}</span>)}</p>
))}
</div>
)}
{bullets.length > 0 && (
<ul class="mt-4 list-none space-y-3 text-base text-gray-500">
{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>
)}
{code !== undefined && (
<div class="mt-4 flex flex-grow flex-col overflow-hidden rounded-xl bg-gray-900 shadow-lg">
{file && <div class="border-b border-white/10 px-4 py-2 font-mono text-xs uppercase tracking-wide text-gray-400">{file}</div>}
<pre class="flex-grow overflow-x-auto px-4 py-4 text-sm leading-relaxed text-gray-100"><code>{code}</code></pre>
</div>
)}
<div class="text-base text-gray-500 [&>p]:mt-2"><slot /></div>
</div>
</div>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.