Page MenuHomeSealhub

dynamic-grid.jdd.tsx
No OneTemporary

dynamic-grid.jdd.tsx

import type { FlatTemplatable } from "tempstream";
import { TempstreamJSX } from "tempstream";
import type {
ComponentToHTMLArgs,
ExtractParsed,
ExtractStructuredComponentArgumentsParsed,
JDDContext,
} from "@sealcode/jdd";
import { Component, ComponentArguments } from "@sealcode/jdd";
type ExtractArray<T> = T extends Array<infer X> ? X : never;
const generate_id = (function* () {
while (true) {
for (let i = 1; i <= 10000; i++) {
yield i;
}
}
})();
const component_arguments = {
heading: new ComponentArguments.ShortText(),
tabs: new ComponentArguments.List(
new ComponentArguments.Structured({
name: new ComponentArguments.ShortText().setExampleValues([
"Tab 1",
"Tab 2",
"Tab 3",
]),
tiles: new ComponentArguments.List(
new ComponentArguments.Structured({
title: new ComponentArguments.ShortText(),
subtitle: new ComponentArguments.ShortText(),
url: new ComponentArguments.ShortText(),
photo: new ComponentArguments.Structured({
image: new ComponentArguments.Image(),
alt: new ComponentArguments.ShortText(),
}),
shape: new ComponentArguments.Enum([
"square",
"horizontal",
"vertical",
]),
})
),
buttons: new ComponentArguments.List(
new ComponentArguments.Structured({
text: new ComponentArguments.ShortText().setExampleValues([
"Button 1",
"Button 2",
"Button 3",
]),
color: new ComponentArguments.Enum(["dark", "bright"] as const),
link: new ComponentArguments.ShortText(),
})
),
})
),
} as const;
export class DynamicGrid extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
getTitle(
_: JDDContext,
args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>
) {
return args.heading || null;
}
public image_sizes = {
square: { width: 700, height: 700 },
horizontal: { width: 824, height: 400 },
vertical: { width: 400, height: 824 },
};
renderTile(
jdd_context: JDDContext,
tile: ExtractArray<
ExtractArray<ExtractParsed<typeof component_arguments.tabs>>["tiles"]
>
) {
return (
<div class={["tile", tile.shape]}>
<a href={[tile.url]}>
<div class="tile-content">
<div class="tile-content-wrapper">
<h3 class="tile-title">{tile.title}</h3>
<p class="tile-subtitle">{tile.subtitle}</p>
</div>
<div class="spacer"></div>
</div>
{(["square", "horizontal", "vertical"] as const).map((shape) => (
<div class={["tile-image", `tile-image--${shape}`]}>
{!tile.photo
? ""
: jdd_context.render_image(tile.photo.image, {
sizesAttr:
"(max-width: 730px) 100vw, (max-width: 980px) 50vw, 810px",
alt: tile.photo.alt,
container: {
...this.image_sizes[shape],
objectFit: "cover",
},
crop: this.image_sizes[shape],
imgStyle: "display: none;",
})}
</div>
))}
</a>
</div>
);
}
composeTab(
jdd_context: JDDContext,
tab: ExtractArray<ExtractParsed<typeof component_arguments.tabs>>,
tab_id: string
) {
return (
<div class="tab-container" id={tab_id}>
<div class="tiles-container">
{tab.tiles.map((tile) => this.renderTile(jdd_context, tile))}
</div>
<div class="buttons-container">
{tab.buttons.map((button) => (
<a class={["button", button.color]} href={button.link}>
{button.text}
</a>
))}
</div>
</div>
);
}
toHTML(
{
args: { heading, tabs },
jdd_context,
classes,
index,
}: ComponentToHTMLArgs<typeof component_arguments>,
tab_style_when_active = `border-bottom-color: #fff;
border-top-color: #b721ff;
background: #fff;
color: #222;`
): FlatTemplatable {
const { value: id } = generate_id.next();
return (
<div
class={["dynamic-grid-component", ...classes]}
style={`--jdd-index: ${index}`}
>
<h2 class="dynamic-grid-title">{heading}</h2>
<ul class="tabs-menu">
{tabs.map((tab, index) => {
return (
<li class="tabs-menu-button">
<label for={`input-${id}-${index}`}>{tab.name}</label>
{
/* HTML */ `<style>
body:has(#input-${id}-${index}:checked)
li:has([for="input-${id}-${index}"]) {
${tab_style_when_active}
}
</style>`
}
</li>
);
})}
</ul>
{tabs.map((tab, index) => {
return (
<section>
{this.composeTab(jdd_context, tab, `tab-${id}-${index}`)}
{
/* HTML */ `<style>
body:has(#input-${id}-${index}:checked)
.tab-container#tab-${id}-${index} {
display: block;
}
</style>`
}
<input
name={`tabs-menu-${id}`}
class="tabs-menu-radio"
type="radio"
id={`input-${id}-${index}`}
checked={index == 0}
/>
</section>
);
})}
</div>
);
}
}

File Metadata

Mime Type
text/html
Expires
Mon, Dec 23, 00:54 (3 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
556714
Default Alt Text
dynamic-grid.jdd.tsx (4 KB)

Event Timeline