Update to the new NestedComponent API. Add side content to Tekst JDD component

This commit is contained in:
Kuba Orlik 2026-07-16 23:16:52 +02:00
parent e2cf4c0cbd
commit ac99ddda92
7 changed files with 92 additions and 40 deletions

32
package-lock.json generated
View File

@ -14,8 +14,8 @@
"@koa/router": "^12.0.1", "@koa/router": "^12.0.1",
"@sealcode/add-to-head": "^1.0.0", "@sealcode/add-to-head": "^1.0.0",
"@sealcode/file-manager": "^1.0.2", "@sealcode/file-manager": "^1.0.2",
"@sealcode/jdd": "^0.8.6", "@sealcode/jdd": "^0.8.8",
"@sealcode/jdd-editor": "^0.2.23", "@sealcode/jdd-editor": "^0.2.24",
"@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/monaco-wrapper": "^0.0.4",
"@sealcode/sealgen": "^0.19.21", "@sealcode/sealgen": "^0.19.21",
"@sealcode/show-first-row": "^0.1.0", "@sealcode/show-first-row": "^0.1.0",
@ -1357,9 +1357,9 @@
} }
}, },
"node_modules/@sealcode/jdd": { "node_modules/@sealcode/jdd": {
"version": "0.8.6", "version": "0.8.8",
"resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.6.tgz", "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.8.tgz",
"integrity": "sha512-IPntFEG/pi/ut85Fz0+eFCb0416uFYmugUKaiHyH2VQ0TKBo3MLQj7V6v8mWLNeOKAEkvejROUs0zbaJuTpgvA==", "integrity": "sha512-BsEkKNMFaHPna8wOiDVJMx/t81zBdWE9q2ckBnqEgbgnqvcTNNmEMpvkQYCndQP07OvW8kwkH7YYIynf+ajjPw==",
"dependencies": { "dependencies": {
"@sealcode/file-manager": "^1.0.2", "@sealcode/file-manager": "^1.0.2",
"@sealcode/ts-predicates": "^0.5.3", "@sealcode/ts-predicates": "^0.5.3",
@ -1380,12 +1380,12 @@
} }
}, },
"node_modules/@sealcode/jdd-editor": { "node_modules/@sealcode/jdd-editor": {
"version": "0.2.23", "version": "0.2.24",
"resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.23.tgz", "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.24.tgz",
"integrity": "sha512-YWzzY7bN27M8rwbjVn8/GanQbqRj5BORIFm5VxkAmu2xeZwvXd64G0547CIqQV1yL5Z2q/hs1d5VvlXVwnCYBw==", "integrity": "sha512-gL9ZJsPhN13ORGlK2mDMpFQYMtdKVfhGa0I+lq8j9VCsPg6I1ZKlgIrltWxVf7i8juN9GXM5imp5bojSkD1IAA==",
"dependencies": { "dependencies": {
"@koa/router": "^13.1.0", "@koa/router": "^13.1.0",
"@sealcode/jdd": "^0.8.6", "@sealcode/jdd": "^0.8.8",
"@sealcode/monaco-wrapper": "^0.0.6", "@sealcode/monaco-wrapper": "^0.0.6",
"@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealcodemirror": "^5.70.0-beta5",
"@sealcode/sealgen": "^0.19.6", "@sealcode/sealgen": "^0.19.6",
@ -16000,9 +16000,9 @@
} }
}, },
"@sealcode/jdd": { "@sealcode/jdd": {
"version": "0.8.6", "version": "0.8.8",
"resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.6.tgz", "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.8.tgz",
"integrity": "sha512-IPntFEG/pi/ut85Fz0+eFCb0416uFYmugUKaiHyH2VQ0TKBo3MLQj7V6v8mWLNeOKAEkvejROUs0zbaJuTpgvA==", "integrity": "sha512-BsEkKNMFaHPna8wOiDVJMx/t81zBdWE9q2ckBnqEgbgnqvcTNNmEMpvkQYCndQP07OvW8kwkH7YYIynf+ajjPw==",
"requires": { "requires": {
"@sealcode/file-manager": "^1.0.2", "@sealcode/file-manager": "^1.0.2",
"@sealcode/ts-predicates": "^0.5.3", "@sealcode/ts-predicates": "^0.5.3",
@ -16032,12 +16032,12 @@
} }
}, },
"@sealcode/jdd-editor": { "@sealcode/jdd-editor": {
"version": "0.2.23", "version": "0.2.24",
"resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.23.tgz", "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.24.tgz",
"integrity": "sha512-YWzzY7bN27M8rwbjVn8/GanQbqRj5BORIFm5VxkAmu2xeZwvXd64G0547CIqQV1yL5Z2q/hs1d5VvlXVwnCYBw==", "integrity": "sha512-gL9ZJsPhN13ORGlK2mDMpFQYMtdKVfhGa0I+lq8j9VCsPg6I1ZKlgIrltWxVf7i8juN9GXM5imp5bojSkD1IAA==",
"requires": { "requires": {
"@koa/router": "^13.1.0", "@koa/router": "^13.1.0",
"@sealcode/jdd": "^0.8.6", "@sealcode/jdd": "^0.8.8",
"@sealcode/monaco-wrapper": "^0.0.6", "@sealcode/monaco-wrapper": "^0.0.6",
"@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealcodemirror": "^5.70.0-beta5",
"@sealcode/sealgen": "^0.19.6", "@sealcode/sealgen": "^0.19.6",

View File

@ -97,8 +97,8 @@
"@koa/router": "^12.0.1", "@koa/router": "^12.0.1",
"@sealcode/add-to-head": "^1.0.0", "@sealcode/add-to-head": "^1.0.0",
"@sealcode/file-manager": "^1.0.2", "@sealcode/file-manager": "^1.0.2",
"@sealcode/jdd": "^0.8.6", "@sealcode/jdd": "^0.8.8",
"@sealcode/jdd-editor": "^0.2.23", "@sealcode/jdd-editor": "^0.2.24",
"@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/monaco-wrapper": "^0.0.4",
"@sealcode/sealgen": "^0.19.21", "@sealcode/sealgen": "^0.19.21",
"@sealcode/show-first-row": "^0.1.0", "@sealcode/show-first-row": "^0.1.0",

View File

@ -0,0 +1,10 @@
.quote {
background-color: var(--color-brand-accent);
color: var(--color-brand-text-on-accent);
padding: 16px;
blockquote {
padding: 0;
margin: 0;
}
}

View File

@ -0,0 +1,27 @@
import { TempstreamJSX } from "tempstream";
import type { ComponentToHTMLArgs } from "@sealcode/jdd";
import { Component, ComponentArguments } from "@sealcode/jdd";
const component_arguments = {
content: new ComponentArguments.Markdown(),
signature: new ComponentArguments.ShortText(),
} as const;
export class Quote extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
async toHTML({
args: { content, signature },
classes,
jdd_context: { render_markdown, language },
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
return (
<div class={["quote", ...classes]}>
<blockquote>{render_markdown(language, content)}</blockquote>
<p>{signature}</p>
</div>
);
}
}

View File

@ -21,14 +21,8 @@ export class SplitView extends Component<typeof component_arguments> {
args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments> args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>
) { ) {
const result = [ const result = [
...ComponentArguments.NestedComponent.getCSSClumpsForNested( ...(args?.component1?.getCSSClumps(jdd_context) || []),
jdd_context, ...(args?.component2?.getCSSClumps(jdd_context) || []),
(args?.component1 as Record<string, unknown>) || {}
),
...ComponentArguments.NestedComponent.getCSSClumpsForNested(
jdd_context,
(args?.component2 as Record<string, unknown>) || {}
),
]; ];
return result; return result;
} }
@ -40,18 +34,8 @@ export class SplitView extends Component<typeof component_arguments> {
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> { }: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
return ( return (
<div class={["split-view", ...classes]}> <div class={["split-view", ...classes]}>
<div class="split-view__half"> <div class="split-view__half">{component1?.render(jdd_context)}</div>
{ComponentArguments.NestedComponent.render({ <div class="split-view__half">{component2?.render(jdd_context)}</div>
jdd_context,
data: component1 as Record<string, unknown>,
})}
</div>
<div class="split-view__half">
{ComponentArguments.NestedComponent.render({
jdd_context,
data: component2 as Record<string, unknown>,
})}
</div>
</div> </div>
); );
} }

View File

@ -31,4 +31,20 @@
background-color: var(--color-brand-text-bg); background-color: var(--color-brand-text-bg);
color: var(--color-brand-text-accent2); color: var(--color-brand-text-accent2);
} }
.side-content {
float: right;
max-width: 250px;
margin: 0 0 16px 16px;
container-type: inline-size;
width: 100%;
margin-right: calc(-1 * var(--bleed-outer-width));
@container (max-width: 570px) {
float: none;
max-width: 100%;
margin: 0;
margin-bottom: var(--row-gap);
}
}
} }

View File

@ -10,6 +10,7 @@ import { Component, ComponentArguments } from "@sealcode/jdd";
const component_arguments = { const component_arguments = {
color: new ComponentArguments.Enum(["transparent", "normal", "accent", "accent2"]), color: new ComponentArguments.Enum(["transparent", "normal", "accent", "accent2"]),
content: new ComponentArguments.Markdown(), content: new ComponentArguments.Markdown(),
side_content: new ComponentArguments.NestedComponent(),
} as const; } as const;
export class Tekst extends Component<typeof component_arguments> { export class Tekst extends Component<typeof component_arguments> {
@ -24,17 +25,31 @@ export class Tekst extends Component<typeof component_arguments> {
return args.content.slice(0, 20) + "..." || null; return args.content.slice(0, 20) + "..." || null;
} }
getCSSClumps(
jdd_context: JDDContext,
args: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>
) {
const result = args?.side_content?.getCSSClumps(jdd_context) || [];
return result;
}
toHTML({ toHTML({
args: { color, content }, args: { color, content, side_content },
classes, classes,
jdd_context: { render_markdown, language }, jdd_context,
index, index,
}: ComponentToHTMLArgs<typeof component_arguments>): FlatTemplatable { }: ComponentToHTMLArgs<typeof component_arguments>): FlatTemplatable {
const { render_markdown, language } = jdd_context;
return ( return (
<div <div
class={["tekst markdown", ...classes, `tekst--color-${color}`]} class={["tekst markdown", ...classes, `tekst--color-${color}`]}
style={`--jdd-index: ${index}`} style={`--jdd-index: ${index}`}
> >
{side_content.isEmpty() ? (
""
) : (
<div class="side-content">{side_content.render(jdd_context)}</div>
)}
{render_markdown(language, content)} {render_markdown(language, content)}
</div> </div>
); );