From 82b62a52e972503f0db1e9312f928608ab9ef2bd Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sun, 9 Aug 2026 22:10:57 +0200 Subject: [PATCH] Add icon tiles grid component --- .../icon-tiles-grid/icon-tiles-grid.css | 59 ++++++++++++++++++ .../icon-tiles-grid/icon-tiles-grid.jdd.tsx | 60 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.css create mode 100644 src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.jdd.tsx diff --git a/src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.css b/src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.css new file mode 100644 index 0000000..8b86c0a --- /dev/null +++ b/src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.css @@ -0,0 +1,59 @@ +.icon-tiles-grid { + container-type: inline-size; + + &.icon-tiles-grid--bleed { + grid-column: bleed; + } + + .icon-tiles-grid__grid { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 16px; + width: max-content; + max-width: 100cqw; + margin: 0 auto; + + @container (max-width: 900px) { + grid-template-columns: 1fr 1fr; + } + + @container (max-width: 600px) { + grid-template-columns: 1fr; + } + + .icon-tiles-grid__tile { + border-radius: 16px; + padding: 40px; + background-color: var(--tile-bg-color); + display: grid; + grid-template-rows: subgrid; + grid-row: span 3; + flex-flow: column; + gap: 32px; + min-height: 320px; + max-width: 400px; + + &, + * { + color: var(--tile-fg-color); + } + + svg { + width: 48px; + height: 48px; + + * { + fill: var(--tile-fg-color) !important; + } + } + + .name { + font-size: 28px; + } + + .description { + font-size: 18px; + } + } + } +} diff --git a/src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.jdd.tsx b/src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.jdd.tsx new file mode 100644 index 0000000..0a290da --- /dev/null +++ b/src/back/jdd-components/icon-tiles-grid/icon-tiles-grid.jdd.tsx @@ -0,0 +1,60 @@ +import { TempstreamJSX } from "tempstream"; +import type { ComponentToHTMLArgs } from "@sealcode/jdd"; +import { Component, ComponentArguments as Args, insert_nbsp } from "@sealcode/jdd"; +import { getAllIconNames, icon } from "src/back/icons.js"; +import { getColorVariables, getFgColorVariable } from "src/back/colors.js"; + +const component_arguments = { + title: new Args.ShortText(), + description: new Args.Markdown(), + bleed: new Args.Boolean(), + tiles: new Args.List( + new Args.Structured({ + icon: new Args.Enum(getAllIconNames), + color: new Args.Enum(async () => + getColorVariables().filter( + (e) => !e.includes("text") && !e.includes("link") + ) + ), + name: new Args.ShortText(), + description: new Args.ShortText(), + }) + ), +} as const; + +export class IconTilesGrid extends Component { + getArguments() { + return component_arguments; + } + + async toHTML({ + args: { title, description, tiles, bleed }, + classes, + jdd_context: { render_markdown, language }, + }: ComponentToHTMLArgs): Promise { + return ( +
+

{title} • IconTilesGrid

+
{render_markdown(language, description)}
+
+ {tiles.map((tile) => ( +
+
{icon(tile.icon)}
+
{insert_nbsp(tile.name)}
+
{insert_nbsp(tile.name)}
+
+ ))} +
+
+ ); + } +}