docs/components/Hero.astro
Rama master · réplica de lectura del repositorio original.
---
import { LinkButton } from "@astrojs/starlight/components";
import DraftContentNotice from "@astrojs/starlight/components/DraftContentNotice.astro";
const { data } = Astro.locals.starlightRoute.entry;
const { title = data.title, tagline, image, actions = [] } = data.hero || {};
const imageAttrs = {
loading: "eager" as const,
decoding: "async" as const,
alt: image?.alt || "",
};
let darkImage: ImageMetadata | undefined;
let lightImage: ImageMetadata | undefined;
let rawHtml: string | undefined;
if (image) {
if ("file" in image) {
darkImage = image.file;
} else if ("dark" in image) {
darkImage = image.dark;
lightImage = image.light;
} else {
rawHtml = image.html;
}
}
---
<div class="hero">
{
darkImage && (
<img
src={darkImage.src}
width={darkImage.width}
height={darkImage.height}
{...imageAttrs}
class:list={{ "light:sl-hidden": Boolean(lightImage) }}
/>
)
}
{
lightImage && (
<img
src={lightImage.src}
width={lightImage.width}
height={lightImage.height}
{...imageAttrs}
class="dark:sl-hidden"
/>
)
}
{rawHtml && <div class="hero-html sl-flex" set:html={rawHtml} />}
<div class="sl-flex stack">
<div class="sl-flex copy">
<h1 id="_top" data-page-title set:html={title} />
{data.draft && <DraftContentNotice />}
{tagline && <div class="tagline" set:html={tagline} />}
</div>
{
actions.length > 0 && (
<div class="sl-flex actions">
{actions.map(
({ attrs: { class: className, ...attrs } = {}, icon, link: href, text, variant }) => (
<LinkButton {href} {variant} icon={icon?.name} class:list={[className]} {...attrs}>
{text}
{icon?.html && <Fragment set:html={icon.html} />}
</LinkButton>
),
)}
</div>
)
}
</div>
</div>
<style>
@layer starlight.core {
.hero {
display: grid;
grid-template-columns: 100%;
align-items: center;
gap: 1.5rem;
padding-bottom: 1rem;
}
.hero > img,
.hero > .hero-html {
object-fit: contain;
width: min(100%, 48rem);
max-width: 100%;
min-width: 0;
height: auto;
margin-inline: auto;
}
.hero > img {
border: 1px solid var(--sl-color-gray-5);
border-radius: 1rem;
box-shadow: 0 24px 60px rgb(7 16 14 / 22%);
}
.stack {
min-width: 0;
flex-direction: column;
gap: clamp(1.5rem, calc(1.5rem + 1vw), 2rem);
text-align: center;
}
.copy {
flex-direction: column;
gap: 1rem;
align-items: center;
}
.copy > * {
max-width: 50ch;
}
h1 {
color: var(--sl-color-white);
font-size: clamp(var(--sl-text-3xl), calc(0.25rem + 5vw), var(--sl-text-6xl));
font-weight: 700;
line-height: var(--sl-line-height-headings);
}
.tagline {
color: var(--sl-color-gray-2);
font-size: clamp(var(--sl-text-base), calc(0.0625rem + 2vw), var(--sl-text-xl));
}
.actions {
flex-wrap: wrap;
justify-content: center;
gap: 1rem 2rem;
}
@media (min-width: 50rem) {
.hero {
grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
gap: clamp(2rem, 4vw, 4rem);
padding-block: clamp(2.5rem, calc(1rem + 10vmin), 10rem);
}
.hero > img,
.hero > .hero-html {
order: 2;
width: 100%;
}
.stack {
text-align: start;
}
.copy {
align-items: flex-start;
}
.actions {
justify-content: flex-start;
}
}
}
</style>