Hero
A landing page's opening: eyebrow, headline, lead, buttons, and a picture or code on the side.
Demo
Now in beta
Ship the whole app in one file
Routes, views and live components in a language made for the web. No build step, no framework to wire up.
route GET / = <html><body> <Counter start={5}/> </body></html>Centred without a side; words left and the picture or code right with one. On a phone the side goes under.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/hero.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/hero.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/hero.qwe
view HeroDemo() = <div.demo-stack> <Hero id="hero-demo-center" eyebrow="Now in beta" title="Ship the whole app in one file" text="Routes, views and live components in a language made for the web. No build step, no framework to wire up."> <Button size="lg" href="#hero">Get started</Button> <Button size="lg" variant="outline" href="#hero">Read the docs</Button> </Hero> <Hero title="See the code" level={2} text="A route, a view and a component: the whole page." side={<CodeBlock code={"route GET / =\n <html><body>\n <Counter start={5}/>\n </body></html>"} language="quillo"/>}> <Button href="#hero">Try it</Button> </Hero> <p.demo-note>Centred without a side; words left and the picture or code right with one. On a phone the side goes under.</p> </div>Source
ui/hero.qwe
// Hero: the first thing on a landing page: a small line above a big title, a// sentence or two, the buttons, and, beside them, a picture or a block of code.//// <Hero eyebrow="Now in beta" title="Ship the whole app in one file"// text="Routes, views and live components in a language made for the web.">// <Button size="lg" href="/start">Get started</Button>// <Button size="lg" variant="outline" href="/docs">Read the docs</Button>// </Hero>// <Hero title="See it run" image="/img/screen.png" image_alt="The dashboard"> ... </Hero>// <Hero title="Hello, world" side={<CodeBlock code={hello} language="quillo"/>}> ... </Hero>//// eyebrow: the small line above the title. title: the headline (an <h1>; level// changes the heading's level, 2 for a hero lower on the page). text: the lead// under it. children: what goes under the text, usually buttons, laid out in a row.// image and image_alt: a picture on the side; side: any HTML there instead (code,// a video, a form). With neither, the words are centred; with one, they sit on// the left and it on the right (the picture under them on a phone). align:// "start" or "center" to say so yourself. size: "md" (default) or "lg", a bigger// title and more room. id: the section's id.import ui/theme.qwe use ui_clslet hero_css = css`.ui-hero { display: grid; gap: 32px; align-items: center; padding: 56px 24px; font: 16px/1.6 var(--ui-font); color: var(--ui-fg); }.ui-hero-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }.ui-hero-lg { padding: 88px 24px; gap: 48px; }.ui-hero-words { display: grid; gap: 14px; justify-items: start; text-align: left; }.ui-hero-center .ui-hero-words { justify-items: center; text-align: center; max-width: 720px; margin: 0 auto; }.ui-hero-eyebrow { margin: 0; color: var(--ui-accent); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }.ui-hero-title { margin: 0; font-size: clamp(32px, 5vw, 48px); font-weight: 750; line-height: 1.1; letter-spacing: -.02em; }.ui-hero-lg .ui-hero-title { font-size: clamp(38px, 6.5vw, 64px); }.ui-hero-text { margin: 0; max-width: 58ch; color: var(--ui-muted); font-size: 18px; }.ui-hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; }.ui-hero-center .ui-hero-actions { justify-content: center; }.ui-hero-side { min-width: 0; }.ui-hero-side > img { display: block; width: 100%; height: auto; border-radius: var(--ui-radius); box-shadow: var(--ui-shadow-lg); }.ui-hero-side > :first-child { margin-top: 0; }@media (max-width: 760px) { .ui-hero { padding: 40px 16px; } .ui-hero-split { grid-template-columns: minmax(0, 1fr); }}`view Hero(title: str, eyebrow: str? = null, text: str? = null, image: str? = null, image_alt: str = "", side = null, align: str? = null, size: str = "md", level: int = 1, id: str? = null, class: str? = null, children) { style global hero_css let aside = side ?? (image != null ? <img src={image} alt={image_alt} loading="lazy"/> : null) let how = align ?? (aside != null ? "start" : "center") let heading = match level { 2 => <h2.ui-hero-title>{title}</h2> 3 => <h3.ui-hero-title>{title}</h3> _ => <h1.ui-hero-title>{title}</h1> } <section id={id} class={ui_cls(["ui-hero", `ui-hero-${how}`, aside != null && "ui-hero-split", size == "lg" && "ui-hero-lg", class])}> <div.ui-hero-words> {eyebrow != null && <p.ui-hero-eyebrow>{eyebrow}</p>} {heading} {text != null && <p.ui-hero-text>{text}</p>} {children != null && <div.ui-hero-actions>{children}</div>} </div> {aside != null && <div.ui-hero-side>{aside}</div>} </section>}Related
CtaSectionA call-to-action band: a title, a line and the buttons, filled, tinted or outlined, centred or split.7 views · 6 downloadsCoverA block as tall as the screen with one thing in its middle, and something at its top and bottom if given.7 views · 7 downloadsSectionA part of a page under its title and a line about it, kept to a readable width, with room above and below.6 views · 5 downloadsAnnouncementBarA slim bar at the top with one message, a badge and a link, closed for good once dismissed.6 views · 5 downloadsBlogListPosts as cards in a grid or rows down the page: picture, tags, title, excerpt, author and date.8 views · 7 downloadsFeatureGridA grid of a product's features, each an icon, a title and a sentence, from a list or written by hand (Feature).7 views · 4 downloads
Thread
Thread 0 posts
On Hero: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.