LogoCloud
A row of logos, grey until hovered, with a line saying what they are; each can be a link.
Demo
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/logo_cloud.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/logo_cloud.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/logo_cloud.qwe
// A wordmark drawn in SVG, so the demo needs no image files.fn logo_cloud_demo_mark(text: str, color: str) -> str { let w = 36 + len(text) * 15 let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${w} 44" width="${w}" height="44">` + `<circle cx="18" cy="22" r="12" fill="${color}"/>` + `<text x="36" y="30" font-family="Inter, system-ui, sans-serif" font-size="22" font-weight="700" fill="${color}">${text}</text></svg>` `data:image/svg+xml,${url_encode(svg)}`}let logo_cloud_demo_logos = [ { name: "Acme", src: logo_cloud_demo_mark("Acme", "#c62a2f"), href: "https://example.com/acme" }, { name: "Globex", src: logo_cloud_demo_mark("Globex", "#0b6bcb") }, { name: "Initech", src: logo_cloud_demo_mark("Initech", "#18794e") }, { name: "Umbrella", src: logo_cloud_demo_mark("Umbrella", "#7c3aed") }, { name: "Hooli", src: logo_cloud_demo_mark("Hooli", "#d9480f") },]view LogoCloudDemo() = <div.demo-stack style="gap: 32px"> <LogoCloud logos={logo_cloud_demo_logos} label="Trusted by teams at"/> <LogoCloud logos={logo_cloud_demo_logos | take(4)} label={null} size="sm" color={true} align="left"/> <p.demo-note>Logos are grey until the pointer rests on one; the second row keeps its colours.</p> </div>Source
ui/logo_cloud.qwe
// LogoCloud: a row of customers' or partners' logos, grey until the pointer// rests on one, with a line above saying what they are.//// <LogoCloud label="Trusted by" logos={[// { name: "Acme", src: "/logos/acme.svg", href: "https://acme.example" },// { name: "Globex", src: "/logos/globex.svg" },// ]}/>//// logos: a list of { name, src, href? }: name is the logo's alt text (and the// link's name), href makes it a link. label: the line above ("Trusted by");// null for none. size: the logos' height, "sm" (24px), "md" (32px, default) or// "lg" (44px). color: true keeps them in colour all the time. align: "center"// (default), "left" or "between" (spread across the row).import ui/theme.qwe use ui_clslet logo_cloud_css = css`.ui-logo-cloud { display: grid; gap: 18px; font: 13px/1.4 var(--ui-font); color: var(--ui-muted); }.ui-logo-cloud-title { margin: 0; text-align: center; text-transform: uppercase; letter-spacing: .08em; font-size: 12px; font-weight: 600; }.ui-logo-cloud-list { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 24px 44px; margin: 0; padding: 0; list-style: none; }.ui-logo-cloud-left .ui-logo-cloud-title { text-align: left; }.ui-logo-cloud-left .ui-logo-cloud-list { justify-content: flex-start; }.ui-logo-cloud-between .ui-logo-cloud-list { justify-content: space-between; }.ui-logo-cloud-item { display: inline-flex; border-radius: var(--ui-radius-sm); }.ui-logo-cloud-item img { display: block; width: auto; height: var(--h, 32px); filter: grayscale(1); opacity: .55; transition: filter .2s, opacity .2s;}.ui-logo-cloud-item:hover img, .ui-logo-cloud-item:focus-visible img, .ui-logo-cloud-color .ui-logo-cloud-item img { filter: none; opacity: 1; }a.ui-logo-cloud-item:focus-visible { outline: none; box-shadow: var(--ui-focus); }.ui-logo-cloud-sm .ui-logo-cloud-item img { --h: 24px; }.ui-logo-cloud-lg .ui-logo-cloud-item img { --h: 44px; }@media (prefers-reduced-motion: reduce) { .ui-logo-cloud-item img { transition: none; } }`view LogoCloud(logos: list = [], label: str? = "Trusted by", size: str = "md", color: bool = false, align: str = "center", class: str? = null) { style global logo_cloud_css <section class={ui_cls(["ui-logo-cloud", size != "md" && `ui-logo-cloud-${size}`, color && "ui-logo-cloud-color", align != "center" && `ui-logo-cloud-${align}`, class])} aria-label={label ?? "Logos"}> {label != null && <p.ui-logo-cloud-title aria-hidden="true">{label}</p>} <ul.ui-logo-cloud-list> {for l in logos => <li key={l.name}> {get(l, "href") != null ? <a.ui-logo-cloud-item href={get(l, "href")} aria-label={l.name} rel="noopener"><img src={l.src} alt="" loading="lazy"/></a> : <span.ui-logo-cloud-item><img src={l.src} alt={l.name} loading="lazy"/></span>} </li>} </ul> </section>}Related
CoverImageA wide picture with a title, subtitle and actions over a gradient, in three heights.7 views · 7 downloadsBrowserFrameA mock browser window around its content, with the address in its bar, for screenshots and demos.7 views · 6 downloadsCameraCaptureTakes a photo with the camera into a hidden input as a data URL, with retake, and says so when there is no camera.6 views · 6 downloadsFigureAn image (or anything) with a caption and a credit under it, as a figure with its figcaption.8 views · 8 downloadsImageAn image that keeps its shape while it loads, shimmering, and shows a fallback with its alt when it cannot.6 views · 8 downloadsImageCompareBefore and after pictures one over the other, with a divider to drag (or move with the keys) between them.6 views · 9 downloads
Thread
Thread 0 posts
On LogoCloud: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.