contentbit
componentastro-pros-conssource: ok · hit
Pros & Cons Block (Astro)
Paired advantages and disadvantages.
npx shadcn add "https://contentbit.dev/r/astro-pros-cons.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · light@contentbit/core@contentbit/blocks@contentbit/astro
Files1 · source cached 10/15/2026, 4:33:48 AM
src/astro/pros-cons.astro
---
import type { ProsConsData } from '@contentbit/blocks'
import type { ValidatedBlockNode } from '@contentbit/core'
import type { AstroBlockContext } from '@contentbit/astro'
import { splitProsCons } from '@contentbit/blocks'
interface Props {
node: ValidatedBlockNode<unknown>
ctx: AstroBlockContext
}
const { node, ctx } = Astro.props
const { pros, cons } = splitProsCons(node.data as ProsConsData)
const [renderedPros, renderedCons] = await Promise.all([
Promise.all(pros.map((item) => ctx.renderMarkdown(item))),
Promise.all(cons.map((item) => ctx.renderMarkdown(item))),
])
// Inline lucide paths: check, x.
const CHECK = '<path d="M20 6 9 17l-5-5"/>'
const X = '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>'
const columns = [
{
heading: 'Pros',
items: renderedPros,
path: CHECK,
head: 'bg-emerald-500/[0.07] text-emerald-700 dark:text-emerald-400',
mark: 'text-emerald-600 dark:text-emerald-500',
},
{
heading: 'Cons',
items: renderedCons,
path: X,
head: 'bg-rose-500/[0.07] text-rose-700 dark:text-rose-400',
mark: 'text-rose-600 dark:text-rose-500',
},
]
---
<div data-cb-styled class="my-6 grid gap-3 sm:grid-cols-2">
{
columns.map((col) => (
<div class="bg-card overflow-hidden rounded-lg border">
<div class:list={['flex items-center gap-2 border-b px-4 py-2.5', col.head]}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
class="size-3.5"
aria-hidden="true"
set:html={col.path}
/>
<span class="text-xs font-semibold tracking-wider uppercase">{col.heading}</span>
</div>
<ul class="list-none space-y-2 p-4 text-sm">
{col.items.map((html) => (
<li class="flex gap-2.5">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
class:list={['mt-1 size-3.5 shrink-0', col.mark]}
aria-hidden="true"
set:html={col.path}
/>
<div class="min-w-0 leading-relaxed [&>p]:m-0" set:html={html} />
</li>
))}
</ul>
</div>
))
}
</div>