Add crossover component

This commit is contained in:
Kuba Orlik 2026-08-14 14:01:34 +02:00
parent a17056fb17
commit 2ae6bef083
2 changed files with 70 additions and 0 deletions

View File

@ -0,0 +1,5 @@
.crossover {
display: grid;
grid-template-columns: subgrid;
grid-column: screen !important;
}

View File

@ -0,0 +1,65 @@
import { TempstreamJSX } from "tempstream";
import type {
ComponentToHTMLArgs,
ExtractStructuredComponentArgumentsParsed,
JDDContext,
} from "@sealcode/jdd";
import { Component, ComponentArguments } from "@sealcode/jdd";
const component_arguments = {
breakpoints_ascending: new ComponentArguments.List(
new ComponentArguments.Structured({
display_up_to_px: new ComponentArguments.Number(),
content: new ComponentArguments.NestedComponent(),
})
),
} as const;
export class Crossover extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
getCSSClumps(
jdd_context: JDDContext,
args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>
) {
const result = (args.breakpoints_ascending || [])
.map((breakpoint) => breakpoint.content.getCSSClumps(jdd_context))
.flat();
return result;
}
async toHTML({
args: { breakpoints_ascending },
classes,
jdd_context,
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
const uid = crypto.randomUUID();
const id = "id-" + uid;
return (
<div class={["crossover", `crossover--id-${uid}`, ...classes]} id={id}>
{breakpoints_ascending.map((breakpoint) =>
breakpoint.content.render(jdd_context)
)}
{
/* HTML */ `<style>
${breakpoints_ascending
.map(
(breakpoint, index) =>
`@container (min-width: ${breakpoints_ascending[index - 1]?.display_up_to_px || 0}px) and (max-width: ${breakpoint.display_up_to_px}px){#${id} > *:not(:nth-child(${index + 1})){display: none;}}`
)
.join("")}
@container
(min-width: ${breakpoints_ascending.at(-1)
?.display_up_to_px}px) {
#${id} > * {
display: none;
}
}
</style>`
}
</div>
);
}
}