Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 190 additions & 13 deletions znai-docs/znai/llm.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Add: [checkboxes](visuals/checkboxes) fence plugin renders bullet points as an interactive checklist, checked state persists in browser local storage
4 changes: 4 additions & 0 deletions znai-docs/znai/release-notes/2026.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.93

:include-markdowns: 1.93

# 1.92

:include-markdowns: 1.92
Expand Down
1 change: 1 addition & 0 deletions znai-docs/znai/toc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ visuals
images
image-annotations
cards
checkboxes
charts
mermaid-diagrams
SVG
Expand Down
62 changes: 62 additions & 0 deletions znai-docs/znai/visuals/checkboxes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Interactive Checklist

To render an interactive checklist use the `checkboxes` fence plugin.
Each bullet point inside becomes a checkbox users can tick.

```checkboxes
* install cli
* setup environment
* run first example
```

```checkboxes
* install cli
* setup environment
* run first example
```

Note: Checked state is persisted in the browser local storage, so it survives page reloads and revisits.
Changing checklist content resets its checked state. During local preview state is not persisted.

# Complex Content

Bullet points can contain any markdown, including multiple paragraphs and code snippets.

````checkboxes
* install dependencies using package manager

```bash
npm install --save-dev my-tool
```

* validate generated config

```javascript
module.exports = {
preset: "default",
};
```

* commit changes
````

````checkboxes
* install dependencies using package manager

```bash
npm install --save-dev my-tool
```

* validate generated config

```javascript
module.exports = {
preset: "default",
};
```

* commit changes
````

Note: Four backticks were used instead of the usual three. This is done so one fence block can include
another block (code snippet) without confusion. It can be any number of backticks greater than three.
3 changes: 3 additions & 0 deletions znai-reactjs/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@
--znai-card-shadow: 0 2px 2px 0 rgb(0 0 0 / 15%), 0 3px 1px -2px rgb(0 0 0 / 13%), 0 1px 5px 0 rgb(0 0 0 / 22%);
--znai-card-link-separator-color: var(--znai-snippets-outer-border-color);

--znai-checkboxes-border-color: #b0b0b0;
--znai-checkboxes-checked-color: var(--znai-brand-primary-color);

--znai-space-above-next-prev-navigation: 150px;
--znai-space-below-next-prev-navigation: 100px;
--znai-space-left-next-prev-navigation: 50px;
Expand Down
2 changes: 2 additions & 0 deletions znai-reactjs/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ import { attentionBlockDemo } from "./doc-elements/paragraph/AttentionBlock.demo
import { attentionBlockPresentationDemo } from "./doc-elements/paragraph/PresentationAttentionBlock.demo";
import { containerTitleDemo } from "./doc-elements/container/ContainerTitle.demo";
import { cardsDemo } from "./doc-elements/card/CardsDemo";
import { checkboxesDemo } from "./doc-elements/checkboxes/Checkboxes.demo";
import { doxygenPresentationDemo } from "./doc-elements/doxygen/PresentationDoxygen.demo";
import { jsonPresentationDemo } from "./doc-elements/json/PresentationJson.demo";
import { footnoteDemo } from "./doc-elements/footnote/Footnote.demo";
Expand Down Expand Up @@ -190,6 +191,7 @@ registries
.registerAsGrid("SVG", 0, svgDemo)
.registerAsGrid("GraphViz SVG", 0, graphVizSvgDemo)
.registerAsRows("Cards", cardsDemo)
.registerAsRows("Checkboxes", checkboxesDemo)
.registerAsRows("Diagram Legend", diagramLegendDemo)
.registerAsGrid("Keyboard shortcuts", 0, keyboardShortcutsDemo)
.registerAsGrid("Iframe", 0, iframeDemo)
Expand Down
2 changes: 2 additions & 0 deletions znai-reactjs/src/doc-elements/DefaultElementsLibrary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import { PythonMethod } from "./python/PythonMethod";
import { ApiLinkedTextBlock } from "./api/ApiLinkedTextBlock";
import { OpenApiMethodAndUrl } from "./open-api/OpenApiMethodAndUrl";
import { Card } from "./card/Card";
import { Checkboxes } from "./checkboxes/Checkboxes";
import { FootnoteReference } from "./footnote/FootnoteReference";
import { FootnoteBackLinks } from "./footnote/FootnotesList";
import { EmbeddedHtml } from "./html/EmbeddedHtml";
Expand Down Expand Up @@ -183,6 +184,7 @@ presentationElementHandlers.AnnotatedImage = presentationAnnotatedImageHandler
library.AnnotatedImageWithOrderedList = AnnotatedImageWithOrderedList

library.Card = Card;
library.Checkboxes = Checkboxes;

library.FootnoteReference = FootnoteReference;
library.FootnoteBackLinks = FootnoteBackLinks;
Expand Down
77 changes: 77 additions & 0 deletions znai-reactjs/src/doc-elements/checkboxes/Checkboxes.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2026 znai maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

.znai-checkboxes {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 15px;
}

.znai-checkboxes-item {
display: flex;
align-items: flex-start;
gap: 10px;
}

/* 1lh keeps the checkbox centered against the first line of the item content */
.znai-checkboxes-tick-cell {
display: flex;
align-items: center;
height: 1lh;
flex-shrink: 0;
}

.znai-checkboxes-tick {
appearance: none;
width: 16px;
height: 16px;
margin: 0;
border: 2px solid var(--znai-checkboxes-border-color);
border-radius: 4px;
background-color: transparent;
cursor: pointer;
}

.znai-checkboxes-tick:hover {
border-color: var(--znai-checkboxes-checked-color);
}

.znai-checkboxes-tick:focus-visible {
outline: 2px solid var(--znai-checkboxes-checked-color);
outline-offset: 2px;
}

.znai-checkboxes-tick:checked {
border-color: var(--znai-checkboxes-checked-color);
background-color: var(--znai-checkboxes-checked-color);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
background-size: 12px 12px;
background-position: center;
background-repeat: no-repeat;
}

.znai-checkboxes-item-content {
flex: 1;
min-width: 0;
transition: opacity 0.15s ease-in-out;

--znai-single-column-render-width: auto;
}

.znai-checkboxes-item.checked .znai-checkboxes-item-content {
opacity: 0.55;
}
112 changes: 112 additions & 0 deletions znai-reactjs/src/doc-elements/checkboxes/Checkboxes.demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright 2026 znai maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React from "react";

import { Registry } from "react-component-viewer";
import { elementsLibrary } from "../DefaultElementsLibrary";
import { Checkboxes } from "./Checkboxes";

export function checkboxesDemo(registry: Registry) {
registry
.add("one liners", () => (
<Checkboxes elementsLibrary={elementsLibrary} blockId="demo-one-liners" checkboxItems={oneLiners()} />
))
.add("long wrapped text", () => (
<Checkboxes elementsLibrary={elementsLibrary} blockId="demo-long-text" checkboxItems={longText()} />
))
.add("with code snippet", () => (
<Checkboxes elementsLibrary={elementsLibrary} blockId="demo-with-snippet" checkboxItems={withSnippet()} />
));
}

function oneLiners() {
return [
{
id: "install-cli",
content: [paragraph("install cli")],
},
{
id: "setup-environment",
content: [paragraph("setup environment")],
},
{
id: "run-first-example",
content: [paragraph("run first example")],
},
];
}

function longText() {
const longLine =
"review the deployment guide and make sure all the required services are provisioned, " +
"credentials are stored in the secrets manager, and the monitoring dashboards are configured " +
"for every environment including staging and production";

return [
{
id: "review-deployment-guide",
content: [paragraph(longLine)],
},
{
id: "short-follow-up",
content: [paragraph("short follow up")],
},
];
}

function withSnippet() {
return [
{
id: "install-dependencies",
content: [
paragraph("install dependencies using package manager"),
{
type: "Snippet",
lang: "bash",
snippet: "npm install --save-dev my-tool\nnpm run my-tool -- --init\n",
},
],
},
{
id: "validate-config",
content: [
paragraph("validate generated config"),
{
type: "Snippet",
lang: "javascript",
snippet: 'module.exports = {\n preset: "default",\n output: "./build",\n};\n',
},
],
},
{
id: "commit-changes",
content: [paragraph("commit changes")],
},
];
}

function paragraph(text: string) {
return {
type: "Paragraph",
content: [
{
text,
type: "SimpleText",
},
],
};
}
Loading
Loading