feat: support checkbox (closes #646) (#799)
* feat: support checkbox
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
* chore: apply review from jacky
---------
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
1 files added
1 files modified
| New file |
| | |
| | | import { getFullSlug } from "../../util/path" |
| | | |
| | | const checkboxId = (index: number) => `${getFullSlug(window)}-checkbox-${index}` |
| | | |
| | | document.addEventListener("nav", () => { |
| | | const checkboxes = document.querySelectorAll( |
| | | "input.checkbox-toggle", |
| | | ) as NodeListOf<HTMLInputElement> |
| | | checkboxes.forEach((el, index) => { |
| | | const elId = checkboxId(index) |
| | | |
| | | const switchState = (e: Event) => { |
| | | const newCheckboxState = (e.target as HTMLInputElement)?.checked ? "true" : "false" |
| | | localStorage.setItem(elId, newCheckboxState) |
| | | } |
| | | |
| | | el.addEventListener("change", switchState) |
| | | window.addCleanup(() => el.removeEventListener("change", switchState)) |
| | | if (localStorage.getItem(elId) === "true") { |
| | | el.checked = true |
| | | } |
| | | }) |
| | | }) |
| | |
| | | import { JSResource } from "../../util/resources" |
| | | // @ts-ignore |
| | | import calloutScript from "../../components/scripts/callout.inline.ts" |
| | | // @ts-ignore |
| | | import checkboxScript from "../../components/scripts/checkbox.inline.ts" |
| | | import { FilePath, pathToRoot, slugTag, slugifyFilePath } from "../../util/path" |
| | | import { toHast } from "mdast-util-to-hast" |
| | | import { toHtml } from "hast-util-to-html" |
| | |
| | | enableInHtmlEmbed: boolean |
| | | enableYouTubeEmbed: boolean |
| | | enableVideoEmbed: boolean |
| | | enableCheckbox: boolean |
| | | } |
| | | |
| | | const defaultOptions: Options = { |
| | |
| | | enableInHtmlEmbed: false, |
| | | enableYouTubeEmbed: true, |
| | | enableVideoEmbed: true, |
| | | enableCheckbox: false, |
| | | } |
| | | |
| | | const calloutMapping = { |
| | |
| | | }) |
| | | } |
| | | |
| | | if (opts.enableCheckbox) { |
| | | plugins.push(() => { |
| | | return (tree: HtmlRoot, _file) => { |
| | | visit(tree, "element", (node) => { |
| | | if (node.tagName === "input" && node.properties.type === "checkbox") { |
| | | const isChecked = node.properties?.checked ?? false |
| | | node.properties = { |
| | | type: "checkbox", |
| | | disabled: false, |
| | | checked: isChecked, |
| | | class: "checkbox-toggle", |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | return plugins |
| | | }, |
| | | externalResources() { |
| | | const js: JSResource[] = [] |
| | | |
| | | if (opts.enableCheckbox) { |
| | | js.push({ |
| | | script: checkboxScript, |
| | | loadTime: "afterDOMReady", |
| | | contentType: "inline", |
| | | }) |
| | | } |
| | | |
| | | if (opts.callouts) { |
| | | js.push({ |
| | | script: calloutScript, |