Hero component and button element

This commit is contained in:
Kuba Orlik 2025-03-01 17:02:20 +01:00
parent 2c2233647b
commit 8f382823ad
7 changed files with 168 additions and 6 deletions

View File

@ -0,0 +1,21 @@
.button {
padding: 8px 16px;
display: inline-block;
text-decoration: none;
margin: 4px;
cursor: pointer;
&:hover {
filter: brightness(1.1);
}
}
.button--color-accent1 {
background-color: var(--color-brand-accent);
color: var(--color-brand-text-on-accent);
}
.button--color-accent2 {
background-color: var(--color-brand-accent2);
color: var(--color-brand-text-on-accent2);
}

View File

@ -0,0 +1,16 @@
export const button_variants = ["accent1", "accent2"] as const;
type variant = (typeof button_variants)[number];
export function button({
text,
href,
variant,
}: {
text: string;
href: string;
variant: variant;
}): JSX.Element {
return /* HTML */ `<a class="button button--color-${variant}" href="${href}">
${text}
</a>`;
}

View File

@ -40,8 +40,10 @@
--container-width: 50rem; --container-width: 50rem;
/* Fonts */ /* Fonts */
--font-sans-serif: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, --font-sans-serif: "Atkinson Hyperlegible", -apple-system, BlinkMacSystemFont,
helvetica neue, Cantarell, Ubuntu, roboto, noto, helvetica, arial, sans-serif; avenir next, avenir, segoe ui, helvetica neue, Cantarell, Ubuntu, roboto, noto,
helvetica, arial, sans-serif;
--font-slab-serif: "Zilla Slab", serif; --font-slab-serif: "Zilla Slab", serif;
--font-serif: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, --font-serif: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman,
Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji,

View File

@ -0,0 +1,63 @@
.hero {
padding: 16px;
text-align: center;
h1 {
margin-top: 0;
font-size: 48px;
&.hero__title--color-normal {
color: inherit;
}
&.hero__title--color-accent1 {
color: var(--color-brand-accent);
}
&.hero__title--color-accent2 {
color: var(--color-brand-accent2);
}
@container (max-width: 420px) {
font-size: 32px;
}
}
.hero__subtitle {
font-size: 32px;
@container (max-width: 420px) {
font-size: 24px;
}
}
h1,
.hero__subtitle {
text-wrap: balance;
}
&.hero--color-text-fg-on-text-bg {
background-color: var(--color-brand-text-bg);
color: var(--color-brand-text-fg);
}
&.hero--color-text-accent-on-text-bg {
background-color: var(--color-brand-text-bg);
color: var(--color-brand-text-accent);
}
&.hero--color-text-accent2-on-text-bg {
background-color: var(--color-brand-text-bg);
color: var(--color-brand-text-accent2);
}
&.hero--color-text-on-accent-on-accent {
background-color: var(--color-brand-accent);
color: var(--color-brand-text-on-accent);
}
&.hero--color-text-on-accent2-on-accent2 {
background-color: var(--color-brand-accent2);
color: var(--color-brand-text-on-accent2);
}
}

View File

@ -0,0 +1,60 @@
import { TempstreamJSX } from "tempstream";
import type {
ComponentToHTMLArgs,
ExtractStructuredComponentArgumentsParsed,
JDDContext,
} from "@sealcode/jdd";
import { Component, ComponentArguments } from "@sealcode/jdd";
import { button, button_variants } from "src/back/elements/button.js";
const component_arguments = {
color: new ComponentArguments.Enum([
"text-fg-on-text-bg",
"text-accent-on-text-bg",
"text-accent2-on-text-bg",
"text-on-accent-on-accent",
"text-on-accent2-on-accent2",
]),
title: new ComponentArguments.ShortText(),
title_color: new ComponentArguments.Enum(["normal", "accent1", "accent2"] as const),
subtitle: new ComponentArguments.ShortText(),
content: new ComponentArguments.Markdown(),
buttons: new ComponentArguments.List(
new ComponentArguments.Structured({
text: new ComponentArguments.ShortText(),
href: new ComponentArguments.ShortText(),
variant: new ComponentArguments.Enum(button_variants),
})
),
} as const;
export class Hero extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
getTitle(
_: JDDContext,
args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>
) {
return args.title || null;
}
async toHTML({
args: { title, title_color, subtitle, content, color, buttons },
classes,
jdd_context: { render_markdown, language },
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
classes.push(`hero--color-${color}`);
return (
<div class={["hero", ...classes]}>
<h1 class={[`hero__title--color-${title_color}`]}>{title}</h1>
<span class={["hero__subtitle"]}>{subtitle}</span>
<div class={["hero__content"]}>{render_markdown(language, content)}</div>
<div class={["hero__buttons"]}>
{buttons.map((button_data) => button(button_data))}
</div>
</div>
);
}
}

View File

@ -1,7 +1,7 @@
{ {
"googleFonts": { "googleFonts": {
"families": { "families": {
"Ubuntu": true, "Atkinson Hyperlegible": true,
"Libre Baskerville": true, "Libre Baskerville": true,
"Ubuntu Mono": true, "Ubuntu Mono": true,
"Anton": true "Anton": true

View File

@ -1,8 +1,8 @@
html { html {
background: var(--color-brand-canvas); background: var(--color-brand-canvas);
font-family: Ubuntu, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", font-family: "Atkinson Hyperlegible", -apple-system, system-ui, BlinkMacSystemFont,
"Segoe UI Emoji", "Segoe UI Symbol", "Lato", "Helvetica Neue", Helvetica, Arial, "Segoe UI", "Segoe UI Emoji", "Segoe UI Symbol", "Lato", "Helvetica Neue",
sans-serif; Helvetica, Arial, sans-serif;
font-size: 14px; font-size: 14px;
} }