@noirmd/previewer 1.2.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/NReditor.cjs +928 -895
  2. package/dist/NReditor.cjs.map +1 -1
  3. package/dist/NReditor.d.cts +1 -1
  4. package/dist/NReditor.d.ts +1 -1
  5. package/dist/NReditor.js +929 -896
  6. package/dist/NReditor.js.map +1 -1
  7. package/dist/admonition.css +55 -0
  8. package/dist/{markdown.css → base.css} +96 -126
  9. package/dist/blockquote.css +16 -0
  10. package/dist/button.css +32 -0
  11. package/dist/card.css +143 -0
  12. package/dist/codeblock.css +59 -0
  13. package/dist/core.cjs +9 -1
  14. package/dist/core.cjs.map +1 -1
  15. package/dist/core.js +9 -1
  16. package/dist/core.js.map +1 -1
  17. package/dist/details.css +45 -0
  18. package/dist/editor.css +56 -9
  19. package/dist/fonts/material-icons-round.woff2 +0 -0
  20. package/dist/index.cjs +929 -882
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +41 -70
  23. package/dist/index.d.ts +41 -70
  24. package/dist/index.js +928 -876
  25. package/dist/index.js.map +1 -1
  26. package/dist/list.css +18 -0
  27. package/dist/modal.css +82 -0
  28. package/dist/react.cjs +929 -885
  29. package/dist/react.cjs.map +1 -1
  30. package/dist/react.d.cts +44 -73
  31. package/dist/react.d.ts +44 -73
  32. package/dist/react.js +928 -879
  33. package/dist/react.js.map +1 -1
  34. package/dist/slide.css +21 -0
  35. package/dist/table.css +36 -0
  36. package/dist/toc.css +45 -0
  37. package/dist/vanilla.cjs +123 -31
  38. package/dist/vanilla.cjs.map +1 -1
  39. package/dist/vanilla.css +32 -677
  40. package/dist/vanilla.d.cts +24 -2
  41. package/dist/vanilla.d.ts +24 -2
  42. package/dist/vanilla.js +119 -31
  43. package/dist/vanilla.js.map +1 -1
  44. package/dist/variables.css +90 -0
  45. package/dist/vue.cjs +1007 -1120
  46. package/dist/vue.cjs.map +1 -1
  47. package/dist/vue.d.cts +63 -214
  48. package/dist/vue.d.ts +63 -214
  49. package/dist/vue.js +1006 -1119
  50. package/dist/vue.js.map +1 -1
  51. package/editor.css +56 -9
  52. package/package.json +5 -10
  53. package/markdown.css +0 -344
package/dist/react.js CHANGED
@@ -1564,7 +1564,7 @@ var require_core = __commonJS({
1564
1564
  });
1565
1565
 
1566
1566
  // react/CustomMarkdownRenderer.tsx
1567
- import React8, { useState as useState3, useEffect as useEffect4, useCallback as useCallback2, useMemo, useId as useId3, useRef as useRef5 } from "react";
1567
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
1568
1568
 
1569
1569
  // core/utils.ts
1570
1570
  function parseCssString(cssText) {
@@ -1610,9 +1610,6 @@ function extractAttributes(text) {
1610
1610
  return { text: cleanedText, classes: classList.join(" "), id };
1611
1611
  }
1612
1612
  var _scopeCounter = 0;
1613
- function resetScopeCounter() {
1614
- _scopeCounter = 0;
1615
- }
1616
1613
  function generateScopeId() {
1617
1614
  return `scope-${++_scopeCounter}`;
1618
1615
  }
@@ -1660,6 +1657,7 @@ function parseMarkdown(markdown2) {
1660
1657
  if (!markdown2) return [];
1661
1658
  const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
1662
1659
  const result = [];
1660
+ const usedIds = /* @__PURE__ */ new Set();
1663
1661
  let i = 0;
1664
1662
  while (i < lines.length) {
1665
1663
  const line = lines[i];
@@ -1669,7 +1667,14 @@ function parseMarkdown(markdown2) {
1669
1667
  const level = match[1].length;
1670
1668
  const rawText = match[2];
1671
1669
  const { text: text2, classes: classes2, id: customId } = extractAttributes(rawText);
1672
- const id2 = customId || generateId(text2.replace(/->|<-/g, ""));
1670
+ const baseId = customId || generateId(text2.replace(/->|<-/g, ""));
1671
+ let id2 = baseId;
1672
+ let n = 1;
1673
+ while (usedIds.has(id2)) {
1674
+ n++;
1675
+ id2 = `${baseId}-${n}`;
1676
+ }
1677
+ usedIds.add(id2);
1673
1678
  result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0 });
1674
1679
  i++;
1675
1680
  continue;
@@ -1984,9 +1989,6 @@ function splitSlots(rawContent) {
1984
1989
  return slots;
1985
1990
  }
1986
1991
 
1987
- // react/ui-components.tsx
1988
- import { useState, useRef } from "react";
1989
-
1990
1992
  // node_modules/highlight.js/es/core.js
1991
1993
  var import_core = __toESM(require_core(), 1);
1992
1994
  var core_default = import_core.default;
@@ -10883,7 +10885,7 @@ function shell(hljs) {
10883
10885
  };
10884
10886
  }
10885
10887
 
10886
- // react/highlightSetup.ts
10888
+ // vanilla/highlightSetup.ts
10887
10889
  core_default.registerLanguage("javascript", javascript);
10888
10890
  core_default.registerLanguage("js", javascript);
10889
10891
  core_default.registerLanguage("jsx", javascript);
@@ -10907,729 +10909,996 @@ core_default.registerLanguage("java", java);
10907
10909
  core_default.registerLanguage("csharp", csharp);
10908
10910
  core_default.registerLanguage("cs", csharp);
10909
10911
  core_default.registerLanguage("cpp", cpp);
10910
- core_default.registerLanguage("c", cpp);
10911
10912
  core_default.registerLanguage("go", go);
10912
10913
  core_default.registerLanguage("rust", rust);
10913
- core_default.registerLanguage("rs", rust);
10914
10914
  core_default.registerLanguage("php", php);
10915
10915
  core_default.registerLanguage("ruby", ruby);
10916
- core_default.registerLanguage("rb", ruby);
10917
10916
  core_default.registerLanguage("swift", swift);
10918
10917
  core_default.registerLanguage("kotlin", kotlin);
10919
- core_default.registerLanguage("kt", kotlin);
10920
10918
  core_default.registerLanguage("dart", dart);
10921
10919
  core_default.registerLanguage("yaml", yaml);
10922
- core_default.registerLanguage("yml", yaml);
10923
10920
  core_default.registerLanguage("toml", ini);
10924
- core_default.registerLanguage("ini", ini);
10925
10921
  core_default.registerLanguage("dockerfile", dockerfile);
10926
- core_default.registerLanguage("docker", dockerfile);
10927
10922
  core_default.registerLanguage("diff", diff);
10928
10923
  core_default.registerLanguage("shell", shell);
10929
10924
  var highlightSetup_default = core_default;
10930
10925
 
10931
- // react/ui-components.tsx
10932
- import { Dialog } from "@base-ui/react/dialog";
10933
- import { jsx, jsxs } from "react/jsx-runtime";
10934
- var IconRenderer = ({ iconName, extraClasses = "" }) => {
10935
- if (!iconName) return null;
10936
- const baseClass = `material-symbols-rounded !text-[1em] leading-none align-top ${extraClasses}`;
10926
+ // vanilla/components.ts
10927
+ function createIcon(iconName, extraClasses) {
10928
+ const span = document.createElement("span");
10929
+ const cls = `nr-icon material-icons-round${extraClasses ? ` ${extraClasses}` : ""}`;
10930
+ span.className = cls;
10931
+ span.setAttribute("aria-hidden", "true");
10937
10932
  const isCodepoint = /^[eE][0-9a-fA-F]{3,4}$/.test(iconName);
10938
10933
  if (isCodepoint) {
10939
- return /* @__PURE__ */ jsx(
10940
- "span",
10941
- {
10942
- className: baseClass,
10943
- dangerouslySetInnerHTML: { __html: `&#x${iconName};` },
10944
- "aria-hidden": "true"
10945
- }
10946
- );
10934
+ span.innerHTML = `&#x${iconName};`;
10935
+ } else {
10936
+ span.textContent = iconName;
10947
10937
  }
10948
- return /* @__PURE__ */ jsx("span", { className: baseClass, "aria-hidden": "true", children: iconName });
10949
- };
10950
- var CodeBlock = ({ code, language, title }) => {
10951
- const [copied, setCopied] = useState(false);
10952
- const timerRef = useRef(null);
10938
+ return span;
10939
+ }
10940
+ function createCodeBlock(code, language, title) {
10941
+ const wrapper = document.createElement("div");
10942
+ wrapper.className = "nr-codeblock";
10953
10943
  const lang = language?.split(/[\s{]/)[0]?.trim() || "";
10954
- let html;
10944
+ if (title) {
10945
+ const header = document.createElement("div");
10946
+ header.className = "nr-codeblock__header";
10947
+ header.appendChild(createIcon("description"));
10948
+ const titleSpan = document.createElement("span");
10949
+ titleSpan.textContent = title;
10950
+ header.appendChild(titleSpan);
10951
+ wrapper.appendChild(header);
10952
+ }
10953
+ const pre = document.createElement("pre");
10954
+ pre.className = "nr-codeblock__pre";
10955
+ const codeEl = document.createElement("code");
10956
+ codeEl.className = `language-${lang || "plaintext"}`;
10955
10957
  try {
10956
10958
  if (lang && highlightSetup_default.getLanguage(lang)) {
10957
- html = highlightSetup_default.highlight(code, { language: lang }).value;
10959
+ codeEl.innerHTML = highlightSetup_default.highlight(code, { language: lang }).value;
10958
10960
  } else {
10959
- html = highlightSetup_default.highlightAuto(code).value;
10961
+ codeEl.innerHTML = highlightSetup_default.highlightAuto(code).value;
10960
10962
  }
10961
10963
  } catch {
10962
- html = "";
10964
+ codeEl.textContent = code;
10963
10965
  }
10964
- const handleCopy = () => {
10966
+ pre.appendChild(codeEl);
10967
+ wrapper.appendChild(pre);
10968
+ const copyBtn = document.createElement("button");
10969
+ copyBtn.className = "nr-codeblock__copy";
10970
+ copyBtn.title = "Copy code";
10971
+ const copyIcon = createIcon("content_copy");
10972
+ copyIcon.style.fontSize = "1rem";
10973
+ copyBtn.appendChild(copyIcon);
10974
+ let timer = null;
10975
+ copyBtn.addEventListener("click", () => {
10965
10976
  navigator.clipboard.writeText(code);
10966
- setCopied(true);
10967
- if (timerRef.current) clearTimeout(timerRef.current);
10968
- timerRef.current = setTimeout(() => setCopied(false), 1800);
10969
- };
10970
- return /* @__PURE__ */ jsxs("div", { className: "not-prose my-4 rounded-2xl border border-border overflow-hidden bg-background-secondary-solid/5", children: [
10971
- title && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2 border-b border-border bg-background-secondary-solid/10 text-xs sm:text-sm font-mono text-text-secondary", children: [
10972
- /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded text-base", children: "description" }),
10973
- title
10974
- ] }),
10975
- /* @__PURE__ */ jsx("div", { className: "overflow-auto [&_pre]:m-0 [&_pre]:p-4 [&_pre]:text-xs sm:[&_pre]:text-sm", children: /* @__PURE__ */ jsx("pre", { className: "m-0", children: /* @__PURE__ */ jsx("code", { className: `language-${lang || "plaintext"}`, dangerouslySetInnerHTML: { __html: html } }) }) }),
10976
- /* @__PURE__ */ jsx("button", { className: "absolute top-2 right-2 p-1.5 rounded-lg bg-background-secondary-solid/20 hover:bg-background-secondary-solid/40 transition-colors cursor-pointer border-none text-text-secondary hover:text-text-primary", onClick: handleCopy, title: "Copy code", children: /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded", style: { fontSize: "1rem" }, children: copied ? "check" : "content_copy" }) })
10977
- ] });
10978
- };
10979
- var defaultIcons = {
10977
+ copyIcon.textContent = "check";
10978
+ if (timer) clearTimeout(timer);
10979
+ timer = setTimeout(() => {
10980
+ copyIcon.textContent = "content_copy";
10981
+ }, 1800);
10982
+ });
10983
+ wrapper.appendChild(copyBtn);
10984
+ return wrapper;
10985
+ }
10986
+ var DEFAULT_ADMONITION_ICONS = {
10980
10987
  note: "info",
10981
10988
  info: "lightbulb",
10982
10989
  warning: "warning",
10983
10990
  danger: "report",
10984
- greentext: "subdirectory_play_arrow"
10985
- };
10986
- var typeClasses = {
10987
- note: "border-info/20 bg-info/5 text-info",
10988
- info: "border-info/30 bg-info/10 text-info",
10989
- warning: "border-amber-500/30 bg-amber-500/10 text-amber-500",
10990
- danger: "border-danger/30 bg-danger/10 text-danger",
10991
- greentext: "border-success/30 bg-success/10 text-success"
10991
+ greentext: "subdirectory_arrow_right"
10992
10992
  };
10993
- var Admonition = ({ type, title, icon, className = "", style, children }) => {
10994
- const iconToRender = icon || defaultIcons[type] || "info";
10995
- return /* @__PURE__ */ jsxs(
10996
- "div",
10997
- {
10998
- className: `not-prose rounded-2xl mb-6 border shadow-xs p-4 ${typeClasses[type] || typeClasses.note} ${className}`,
10999
- style,
11000
- children: [
11001
- title && /* @__PURE__ */ jsxs("h5", { className: "font-bold text-base mb-2 m-0 flex items-center gap-2", children: [
11002
- /* @__PURE__ */ jsx(IconRenderer, { iconName: iconToRender, extraClasses: "shrink-0" }),
11003
- /* @__PURE__ */ jsx("span", { children: title })
11004
- ] }),
11005
- /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed opacity-90", children })
11006
- ]
11007
- }
11008
- );
11009
- };
11010
- var Details = ({
11011
- title,
11012
- icon,
11013
- defaultOpen = false,
11014
- className = "",
11015
- style,
11016
- children
11017
- }) => {
11018
- const [isOpen, setIsOpen] = useState(defaultOpen);
10993
+ function createAdmonition(type, title, icon) {
10994
+ const el = document.createElement("div");
10995
+ el.className = `nr-admonition nr-admonition--${type || "note"}`;
10996
+ if (title) {
10997
+ const header = document.createElement("h5");
10998
+ header.className = "nr-admonition__title";
10999
+ const iconToRender = icon || DEFAULT_ADMONITION_ICONS[type] || "info";
11000
+ header.appendChild(createIcon(iconToRender, "nr-admonition__icon"));
11001
+ const titleSpan = document.createElement("span");
11002
+ titleSpan.textContent = title;
11003
+ header.appendChild(titleSpan);
11004
+ el.appendChild(header);
11005
+ }
11006
+ const body = document.createElement("div");
11007
+ body.className = "nr-admonition__body";
11008
+ el.appendChild(body);
11009
+ return el;
11010
+ }
11011
+ function createDetails(title, icon, defaultOpen) {
11012
+ const details = document.createElement("details");
11013
+ details.className = "nr-details";
11014
+ if (defaultOpen) details.open = true;
11015
+ const summary = document.createElement("summary");
11016
+ summary.className = "nr-details__summary";
11019
11017
  const iconToRender = icon || "play_arrow";
11020
- return /* @__PURE__ */ jsxs(
11021
- "details",
11022
- {
11023
- className: `not-prose rounded-2xl border border-border mb-4 bg-background-primary/5 ${className}`,
11024
- open: isOpen,
11025
- style,
11026
- children: [
11027
- /* @__PURE__ */ jsxs(
11028
- "summary",
11029
- {
11030
- className: "cursor-pointer p-4 font-bold flex items-center gap-2 list-none [&::-webkit-details-marker]:hidden hover:text-accent-primary transition-colors",
11031
- onClick: (e) => {
11032
- e.preventDefault();
11033
- setIsOpen((prev) => !prev);
11034
- },
11035
- children: [
11036
- /* @__PURE__ */ jsx(
11037
- IconRenderer,
11038
- {
11039
- iconName: iconToRender,
11040
- extraClasses: `transition-transform ${isOpen ? "rotate-90" : ""}`
11041
- }
11042
- ),
11043
- /* @__PURE__ */ jsx("span", { children: title })
11044
- ]
11045
- }
11046
- ),
11047
- isOpen && /* @__PURE__ */ jsx("div", { className: "px-4 pb-4 border-t border-border pt-3 text-sm leading-relaxed opacity-90 overflow-hidden min-w-0", children })
11048
- ]
11049
- }
11050
- );
11051
- };
11052
- var Modal = ({ title, isOpen, onClose, children }) => {
11053
- return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: (open) => {
11054
- if (!open) onClose();
11055
- }, children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
11056
- /* @__PURE__ */ jsx(Dialog.Backdrop, { className: "fixed inset-0 z-[9999] bg-black/60" }),
11057
- /* @__PURE__ */ jsx(Dialog.Viewport, { className: "fixed inset-0 z-[9999] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(Dialog.Popup, { className: "bg-background-primary border border-border shadow-2xl rounded-3xl w-full max-w-3xl max-h-[85vh] flex flex-col overflow-hidden", children: [
11058
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center p-4 border-b border-border bg-background-secondary-solid/20", children: [
11059
- /* @__PURE__ */ jsx(Dialog.Title, { className: "text-lg font-bold !m-0", children: title }),
11060
- /* @__PURE__ */ jsx(Dialog.Close, { className: "w-8 h-8 rounded-full hover:bg-white/10 flex items-center justify-center transition-colors cursor-pointer border-none bg-transparent", children: /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded text-base", children: "close" }) })
11061
- ] }),
11062
- /* @__PURE__ */ jsx("div", { className: "p-6 overflow-auto min-h-0 text-text-primary [&_h1:first-child]:mt-0 [&_h2:first-child]:mt-0 [&_h3:first-child]:mt-0 [&_h4:first-child]:mt-0 [&_h5:first-child]:mt-0 [&_h6:first-child]:mt-0", children })
11063
- ] }) })
11064
- ] }) });
11065
- };
11066
-
11067
- // react/renderers.tsx
11068
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
11069
- function renderInline(text) {
11070
- if (!text) return text;
11071
- const parsePart = (part, key) => {
11072
- let match2;
11073
- if (match2 = part.match(/^\|\[([^\]]+)\]\|$/)) {
11074
- return /* @__PURE__ */ jsx2(IconRenderer, { iconName: match2[1] }, key);
11075
- }
11076
- if (match2 = part.match(/^!~(.+?)~!$/)) {
11077
- const content = match2[1];
11078
- const parts = content.split(";");
11079
- let color = "currentColor";
11080
- let decorationStyle = "solid";
11081
- let type = "underline";
11082
- let textIndex = 0;
11083
- if (parts[textIndex]?.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) || ["red", "blue", "green", "purple", "orange", "yellow", "pink"].includes(parts[textIndex])) {
11084
- color = parts[textIndex++];
11085
- }
11086
- if (["solid", "double", "dotted", "dashed", "wavy"].includes(parts[textIndex])) {
11087
- decorationStyle = parts[textIndex++];
11088
- }
11089
- if (["underline", "line-through", "overline", "both"].includes(parts[textIndex])) {
11090
- type = parts[textIndex] === "both" ? "underline line-through" : parts[textIndex++];
11091
- }
11092
- const innerText = parts.slice(textIndex).join(";");
11093
- return /* @__PURE__ */ jsx2(
11094
- "span",
11095
- {
11096
- style: {
11097
- textDecoration: `${type} ${decorationStyle} ${color}`,
11098
- textDecorationThickness: "auto"
11099
- },
11100
- children: renderInline(innerText)
11101
- },
11102
- key
11103
- );
11104
- }
11105
- if (match2 = part.match(/%([^%\s]+?)%([\s\S]+?)%%/)) {
11106
- return /* @__PURE__ */ jsx2("span", { style: { color: match2[1] }, children: renderInline(match2[2]) }, key);
11107
- }
11108
- if (match2 = part.match(/^!>([^<]+?)<!$/)) {
11109
- return /* @__PURE__ */ jsx2("span", { className: "bg-text-primary text-bg-primary px-1 rounded hover:bg-transparent transition-colors cursor-pointer", children: renderInline(match2[1]) }, key);
11110
- }
11111
- if (match2 = part.match(/^==(.+?)==$/)) {
11112
- return /* @__PURE__ */ jsx2("mark", { className: "bg-yellow-500/20 text-inherit px-0.5 rounded", children: renderInline(match2[1]) }, key);
11113
- }
11114
- if (match2 = part.match(/^\*\*\*(.+?)\*\*\*$/)) {
11115
- return /* @__PURE__ */ jsx2("strong", { children: /* @__PURE__ */ jsx2("em", { children: renderInline(match2[1]) }) }, key);
11116
- }
11117
- if (match2 = part.match(/^\*\*(.+?)\*\*$/)) {
11118
- return /* @__PURE__ */ jsx2("strong", { children: renderInline(match2[1]) }, key);
11119
- }
11120
- if (match2 = part.match(/^_(.+?)_$/)) {
11121
- return /* @__PURE__ */ jsx2("em", { children: renderInline(match2[1]) }, key);
11122
- }
11123
- if (match2 = part.match(/^~~(.+?)~~$/)) {
11124
- return /* @__PURE__ */ jsx2("del", { children: renderInline(match2[1]) }, key);
11125
- }
11126
- if (match2 = part.match(/^`([^`]+)`$/)) {
11127
- return /* @__PURE__ */ jsx2("code", { className: "text-[0.875em] font-mono bg-background-secondary/50 px-1.5 py-0.5 rounded text-text-primary", children: match2[1] }, key);
11128
- }
11129
- if (match2 = part.match(/^\[([^\]]+?)\]\(([^)]+?)\)$/)) {
11130
- return /* @__PURE__ */ jsx2(
11131
- "a",
11132
- {
11133
- href: match2[2],
11134
- className: "text-accent-primary underline decoration-accent-primary/40 hover:decoration-accent-primary transition-colors",
11135
- target: "_blank",
11136
- rel: "noopener noreferrer",
11137
- children: renderInline(match2[1])
11138
- },
11139
- key
11140
- );
11141
- }
11142
- if (part.startsWith("<") && part.endsWith(">")) {
11143
- return /* @__PURE__ */ jsx2("span", { dangerouslySetInnerHTML: { __html: part } }, key);
11144
- }
11145
- return part;
11146
- };
11147
- const regex = /(\|\[[^\]]+\]\||\*\*\*.+?\*\*\*|\*\*.+?\*\*|_.+?_|~~.+?~~|`[^`]+?`|!~.+?~!|%[^%\s]+?%[\s\S]+?%%|!>.+?<!|==.+?==|\[[^\]]+?\]\([^)]+?\)|<[^>]+>)/g;
11148
- const elements = [];
11149
- let lastIndex = 0;
11150
- let match;
11151
- let keyCounter = 0;
11152
- while ((match = regex.exec(text)) !== null) {
11153
- if (match.index > lastIndex) {
11154
- elements.push(text.slice(lastIndex, match.index));
11018
+ const iconEl = createIcon(iconToRender, "nr-details__icon");
11019
+ summary.appendChild(iconEl);
11020
+ const titleSpan = document.createElement("span");
11021
+ titleSpan.textContent = title || "Details";
11022
+ summary.appendChild(titleSpan);
11023
+ details.addEventListener("toggle", () => {
11024
+ iconEl.classList.toggle("nr-details__icon--open", details.open);
11025
+ });
11026
+ details.appendChild(summary);
11027
+ const body = document.createElement("div");
11028
+ body.className = "nr-details__body";
11029
+ details.appendChild(body);
11030
+ return details;
11031
+ }
11032
+ function createModal(title) {
11033
+ const dialog = document.createElement("dialog");
11034
+ dialog.className = "nr-modal";
11035
+ dialog.addEventListener("click", (e) => {
11036
+ if (e.target === dialog) {
11037
+ dialog.close();
11155
11038
  }
11156
- elements.push(parsePart(match[0], `inline-${keyCounter++}`));
11157
- lastIndex = regex.lastIndex;
11158
- }
11159
- if (lastIndex < text.length) {
11160
- elements.push(text.slice(lastIndex));
11161
- }
11162
- return elements;
11039
+ });
11040
+ const popup = document.createElement("div");
11041
+ popup.className = "nr-modal__popup";
11042
+ const header = document.createElement("div");
11043
+ header.className = "nr-modal__header";
11044
+ const titleEl = document.createElement("h2");
11045
+ titleEl.className = "nr-modal__title";
11046
+ titleEl.textContent = title;
11047
+ header.appendChild(titleEl);
11048
+ const closeBtn = document.createElement("button");
11049
+ closeBtn.className = "nr-modal__close";
11050
+ closeBtn.appendChild(createIcon("close"));
11051
+ closeBtn.addEventListener("click", () => dialog.close());
11052
+ header.appendChild(closeBtn);
11053
+ popup.appendChild(header);
11054
+ const body = document.createElement("div");
11055
+ body.className = "nr-modal__body";
11056
+ popup.appendChild(body);
11057
+ dialog.appendChild(popup);
11058
+ return dialog;
11163
11059
  }
11164
- function renderTable(content) {
11060
+ function createTable(content, renderInline2) {
11165
11061
  const rows = content.split("\n").filter((r) => r.trim());
11166
- if (rows.length < 2) return /* @__PURE__ */ jsx2("p", { children: content });
11062
+ if (rows.length < 2) {
11063
+ const p = document.createElement("p");
11064
+ p.textContent = content;
11065
+ return p;
11066
+ }
11167
11067
  const parseRow = (row) => row.split("|").map((c) => c.trim()).filter(Boolean);
11168
11068
  const headerCells = parseRow(rows[0]);
11169
11069
  const bodyRows = rows.slice(2).map(parseRow);
11170
- return /* @__PURE__ */ jsx2("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs2("table", { className: "w-full text-sm sm:text-base border-collapse my-4", children: [
11171
- /* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: headerCells.map((cell, ci) => /* @__PURE__ */ jsx2("th", { className: "border border-border px-3 py-2 bg-background-secondary-solid/10 text-left font-bold", children: renderInline(cell) }, ci)) }) }),
11172
- /* @__PURE__ */ jsx2("tbody", { children: bodyRows.map((cells, ri) => /* @__PURE__ */ jsx2("tr", { children: cells.map((cell, ci) => /* @__PURE__ */ jsx2("td", { className: "border border-border px-3 py-2", children: renderInline(cell) }, ci)) }, ri)) })
11173
- ] }) });
11070
+ const wrapper = document.createElement("div");
11071
+ wrapper.className = "nr-table-wrap";
11072
+ const table = document.createElement("table");
11073
+ table.className = "nr-table";
11074
+ const thead = document.createElement("thead");
11075
+ const tr = document.createElement("tr");
11076
+ for (const cell of headerCells) {
11077
+ const th = document.createElement("th");
11078
+ th.className = "nr-table__th";
11079
+ th.appendChild(renderInline2(cell));
11080
+ tr.appendChild(th);
11081
+ }
11082
+ thead.appendChild(tr);
11083
+ table.appendChild(thead);
11084
+ const tbody = document.createElement("tbody");
11085
+ for (const cells of bodyRows) {
11086
+ const tr2 = document.createElement("tr");
11087
+ for (const cell of cells) {
11088
+ const td = document.createElement("td");
11089
+ td.className = "nr-table__td";
11090
+ td.appendChild(renderInline2(cell));
11091
+ tr2.appendChild(td);
11092
+ }
11093
+ tbody.appendChild(tr2);
11094
+ }
11095
+ table.appendChild(tbody);
11096
+ wrapper.appendChild(table);
11097
+ return wrapper;
11174
11098
  }
11175
- function renderList(content) {
11099
+ function createList(content, renderInline2) {
11176
11100
  const lines = content.split("\n");
11177
11101
  const items = [];
11178
11102
  for (const line of lines) {
11179
11103
  if (!line.trim()) continue;
11180
11104
  const match = line.match(/^(\s*)([-*+]|\d+\.)\s+(.+)$/);
11181
11105
  if (match) {
11182
- items.push({
11183
- indent: match[1].length,
11184
- marker: match[2],
11185
- text: match[3]
11186
- });
11106
+ items.push({ indent: match[1].length, marker: match[2], text: match[3] });
11187
11107
  }
11188
11108
  }
11189
- if (items.length === 0) return /* @__PURE__ */ jsx2("p", { children: content });
11109
+ if (items.length === 0) {
11110
+ const p = document.createElement("p");
11111
+ p.textContent = content;
11112
+ return p;
11113
+ }
11190
11114
  const isOrdered = /^\d+\.$/.test(items[0].marker);
11191
- const Tag = isOrdered ? "ol" : "ul";
11192
- return /* @__PURE__ */ jsx2(Tag, { className: `${isOrdered ? "list-decimal" : "list-disc"} pl-6 my-3 space-y-1 text-sm sm:text-base`, children: items.map((item, index) => /* @__PURE__ */ jsx2("li", { className: "leading-relaxed", children: renderInline(item.text) }, index)) });
11115
+ const list = document.createElement(isOrdered ? "ol" : "ul");
11116
+ list.className = "nr-list";
11117
+ for (const item of items) {
11118
+ const li = document.createElement("li");
11119
+ li.className = "nr-list__item";
11120
+ li.appendChild(renderInline2(item.text));
11121
+ list.appendChild(li);
11122
+ }
11123
+ return list;
11124
+ }
11125
+ function createTOC(headers, renderInline2) {
11126
+ const nav = document.createElement("nav");
11127
+ nav.className = "nr-toc";
11128
+ const title = document.createElement("div");
11129
+ title.className = "nr-toc__title";
11130
+ title.textContent = "Table of Contents";
11131
+ nav.appendChild(title);
11132
+ const ul = document.createElement("ul");
11133
+ ul.className = "nr-toc__list";
11134
+ for (const h of headers) {
11135
+ const li = document.createElement("li");
11136
+ li.className = `nr-toc__item nr-toc__item--h${h.level}`;
11137
+ const a = document.createElement("a");
11138
+ a.className = "nr-toc__link";
11139
+ a.href = `#${h.id}`;
11140
+ a.appendChild(renderInline2(h.text.replace(/->|<-/g, "").trim()));
11141
+ a.addEventListener("click", (e) => {
11142
+ e.preventDefault();
11143
+ const target = document.getElementById(h.id);
11144
+ if (target) target.scrollIntoView({ behavior: "smooth", block: "start" });
11145
+ });
11146
+ li.appendChild(a);
11147
+ ul.appendChild(li);
11148
+ }
11149
+ nav.appendChild(ul);
11150
+ return nav;
11193
11151
  }
11194
- function extractHeaders(elements) {
11195
- return elements.filter((el) => el.type === "header");
11152
+ function createBlockquote(content, classes, renderInline2) {
11153
+ const el = document.createElement("blockquote");
11154
+ el.className = `nr-blockquote${classes ? ` ${classes}` : ""}`;
11155
+ el.appendChild(renderInline2(content));
11156
+ return el;
11196
11157
  }
11197
11158
 
11198
- // react/directives/AdmonitionDirective.tsx
11199
- import { jsx as jsx3 } from "react/jsx-runtime";
11200
- var AdmonitionDirective = ({
11201
- directiveType,
11202
- props,
11203
- renderSlot
11204
- }) => {
11205
- return /* @__PURE__ */ jsx3(
11206
- Admonition,
11207
- {
11208
- type: directiveType,
11209
- title: props.title,
11210
- icon: props.icon,
11211
- className: props.class,
11212
- style: props.style ? parseCssString(props.style) : void 0,
11213
- children: renderSlot("default")
11159
+ // vanilla/inline.ts
11160
+ function renderInline(text) {
11161
+ const fragment = document.createDocumentFragment();
11162
+ if (!text) return fragment;
11163
+ const regex = /(\|\[[^\]]+\]\||\*\*\*.+?\*\*\*|\*\*.+?\*\*|_.+?_|~~.+?~~|`[^`]+?`|!~.+?~!|%[^%\s]+?%[\s\S]+?%%|!>.+?<!|==.+?==|\[[^\]]+?\]\([^)]+?\)|<[^>]+>)/g;
11164
+ let lastIndex = 0;
11165
+ let match;
11166
+ while ((match = regex.exec(text)) !== null) {
11167
+ if (match.index > lastIndex) {
11168
+ fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
11214
11169
  }
11215
- );
11216
- };
11217
- var AdmonitionDirective_default = AdmonitionDirective;
11170
+ fragment.appendChild(parseInlinePart(match[0]));
11171
+ lastIndex = regex.lastIndex;
11172
+ }
11173
+ if (lastIndex < text.length) {
11174
+ fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
11175
+ }
11176
+ return fragment;
11177
+ }
11178
+ function parseInlinePart(part) {
11179
+ let match;
11180
+ if (match = part.match(/^\|\[([^\]]+)\]\|$/)) {
11181
+ return createIcon(match[1]);
11182
+ }
11183
+ if (match = part.match(/^!~(.+?)~!$/)) {
11184
+ const content = match[1];
11185
+ const parts = content.split(";");
11186
+ let color = "currentColor";
11187
+ let decorationStyle = "solid";
11188
+ let type = "underline";
11189
+ let textIndex = 0;
11190
+ if (parts[textIndex]?.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) || ["red", "blue", "green", "purple", "orange", "yellow", "pink"].includes(parts[textIndex])) {
11191
+ color = parts[textIndex++];
11192
+ }
11193
+ if (["solid", "double", "dotted", "dashed", "wavy"].includes(parts[textIndex])) {
11194
+ decorationStyle = parts[textIndex++];
11195
+ }
11196
+ if (["underline", "line-through", "overline", "both"].includes(parts[textIndex])) {
11197
+ type = parts[textIndex] === "both" ? "underline line-through" : parts[textIndex++];
11198
+ }
11199
+ const innerText = parts.slice(textIndex).join(";");
11200
+ const span = document.createElement("span");
11201
+ span.className = "nr-underline";
11202
+ span.style.textDecoration = `${type} ${decorationStyle} ${color}`;
11203
+ span.style.textDecorationThickness = "auto";
11204
+ span.appendChild(renderInline(innerText));
11205
+ return span;
11206
+ }
11207
+ if (match = part.match(/%([^%\s]+?)%([\s\S]+?)%%/)) {
11208
+ const span = document.createElement("span");
11209
+ span.style.color = match[1];
11210
+ span.appendChild(renderInline(match[2]));
11211
+ return span;
11212
+ }
11213
+ if (match = part.match(/^!>([^<]+?)<!$/)) {
11214
+ const span = document.createElement("span");
11215
+ span.className = "nr-spoiler";
11216
+ span.appendChild(renderInline(match[1]));
11217
+ return span;
11218
+ }
11219
+ if (match = part.match(/^==(.+?)==$/)) {
11220
+ const mark = document.createElement("mark");
11221
+ mark.className = "nr-highlight";
11222
+ mark.appendChild(renderInline(match[1]));
11223
+ return mark;
11224
+ }
11225
+ if (match = part.match(/^\*\*\*(.+?)\*\*\*$/)) {
11226
+ const strong = document.createElement("strong");
11227
+ const em = document.createElement("em");
11228
+ em.appendChild(renderInline(match[1]));
11229
+ strong.appendChild(em);
11230
+ return strong;
11231
+ }
11232
+ if (match = part.match(/^\*\*(.+?)\*\*$/)) {
11233
+ const strong = document.createElement("strong");
11234
+ strong.appendChild(renderInline(match[1]));
11235
+ return strong;
11236
+ }
11237
+ if (match = part.match(/^_(.+?)_$/)) {
11238
+ const em = document.createElement("em");
11239
+ em.appendChild(renderInline(match[1]));
11240
+ return em;
11241
+ }
11242
+ if (match = part.match(/^~~(.+?)~~$/)) {
11243
+ const del = document.createElement("del");
11244
+ del.appendChild(renderInline(match[1]));
11245
+ return del;
11246
+ }
11247
+ if (match = part.match(/^`([^`]+)`$/)) {
11248
+ const code = document.createElement("code");
11249
+ code.className = "nr-inline-code";
11250
+ code.textContent = match[1];
11251
+ return code;
11252
+ }
11253
+ if (match = part.match(/^\[([^\]]+?)\]\(([^)]+?)\)$/)) {
11254
+ const a = document.createElement("a");
11255
+ a.className = "nr-link";
11256
+ a.href = match[2];
11257
+ a.target = "_blank";
11258
+ a.rel = "noopener noreferrer";
11259
+ a.appendChild(renderInline(match[1]));
11260
+ return a;
11261
+ }
11262
+ if (part.startsWith("<") && part.endsWith(">")) {
11263
+ const span = document.createElement("span");
11264
+ span.innerHTML = part;
11265
+ return span;
11266
+ }
11267
+ return document.createTextNode(part);
11268
+ }
11218
11269
 
11219
- // react/directives/CardDirective.tsx
11220
- import React2, { useId } from "react";
11221
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
11222
- var CardDirective = ({
11223
- directiveType,
11224
- props,
11225
- slots,
11226
- renderSlot,
11227
- context,
11228
- options = {}
11229
- }) => {
11230
- const stableId = useId();
11231
- const { title, image, icon, class: customClass, url, target } = props;
11232
- const hasDescription = !!slots.description;
11233
- const { isSingleCard } = options;
11234
- const isModal = directiveType === "card-m";
11235
- const isLink = directiveType === "card-b";
11236
- const modalId = `modal-card-${props.id || stableId}`;
11237
- const wrapperClass = customClass || "";
11238
- const inlineStyles = props.style ? parseCssString(props.style) : {};
11239
- const description = hasDescription ? renderSlot("description") : null;
11240
- const content = renderSlot("content") || renderSlot("default");
11241
- return /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
11242
- /* @__PURE__ */ jsxs3(
11243
- "div",
11244
- {
11245
- className: `flex flex-col h-full rounded-3xl transition-all relative overflow-hidden group border min-w-[18rem] w-[18rem] max-w-[20rem] ${isModal || isLink ? "cursor-pointer !border-accent-primary/10 hover:border-accent-primary/50" : "border-border"} ${wrapperClass}`,
11246
- style: inlineStyles,
11247
- onClick: isModal ? (e) => {
11248
- e.preventDefault();
11249
- e.stopPropagation();
11250
- context.setModals((prev) => ({ ...prev, [modalId]: true }));
11251
- } : isLink && url ? () => window.open(url, "_blank") : void 0,
11252
- role: isModal ? "button" : void 0,
11253
- tabIndex: isModal ? 0 : void 0,
11254
- onKeyDown: isModal ? (e) => {
11255
- if (e.key === "Enter" || e.key === " ") context.setModals((prev) => ({ ...prev, [modalId]: true }));
11256
- } : void 0,
11257
- children: [
11258
- image && /* @__PURE__ */ jsxs3("div", { className: `w-full ${isSingleCard ? "h-[240px]" : "h-[160px]"} overflow-hidden relative transition-all duration-500`, children: [
11259
- /* @__PURE__ */ jsx4("img", { src: image, alt: title || "", className: "w-full h-full object-cover !m-0" }),
11260
- /* @__PURE__ */ jsx4("div", { className: "absolute inset-0 bg-gradient-to-t from-background-primary/40 to-transparent" })
11261
- ] }),
11262
- /* @__PURE__ */ jsxs3("div", { className: `flex flex-col flex-1 bg-background-primary/80 rounded-t-xl p-6 relative ${image ? "-mt-10" : ""} border-t border-white/5 shadow-2xl`, children: [
11263
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3 mb-3", children: [
11264
- icon && /* @__PURE__ */ jsx4("div", { className: "w-10 h-10 text-[1.6em] rounded-xl bg-accent-primary/20 flex items-center justify-center shrink-0 text-accent-primary", children: /* @__PURE__ */ jsx4(IconRenderer, { iconName: icon }) }),
11265
- /* @__PURE__ */ jsx4("h3", { className: "text-base font-black tracking-tight leading-tight !m-0", children: title })
11266
- ] }),
11267
- /* @__PURE__ */ jsxs3("div", { className: "flex-1 flex flex-col gap-2", children: [
11268
- description && /* @__PURE__ */ jsx4("div", { className: "text-sm opacity-80 leading-relaxed font-medium", children: description }),
11269
- directiveType === "card" && content && /* @__PURE__ */ jsx4("div", { className: "mt-2", children: content })
11270
- ] }),
11271
- (isModal || isLink) && /* @__PURE__ */ jsx4("div", { className: "mt-6 flex justify-end", children: isLink && url ? /* @__PURE__ */ jsxs3(
11272
- "a",
11273
- {
11274
- href: url,
11275
- target: "_blank",
11276
- rel: "noopener noreferrer",
11277
- className: "bg-accent-primary/20 hover:bg-accent-primary/30 px-4 py-2 rounded-xl flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest opacity-50 group-hover:opacity-100 group-hover:text-accent-primary transition-all no-underline",
11278
- onClick: (e) => e.stopPropagation(),
11279
- children: [
11280
- /* @__PURE__ */ jsx4(IconRenderer, { iconName: "open_in_new" }),
11281
- " Link"
11282
- ]
11283
- }
11284
- ) : isModal ? /* @__PURE__ */ jsxs3("div", { className: "bg-accent-primary/20 hover:bg-accent-primary/30 px-4 py-2 cursor-pointer rounded-xl flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest opacity-50 group-hover:opacity-100 group-hover:text-accent-primary transition-all", children: [
11285
- /* @__PURE__ */ jsx4(IconRenderer, { iconName: "arrow_forward" }),
11286
- " Abrir"
11287
- ] }) : null })
11288
- ] })
11289
- ]
11290
- }
11291
- ),
11292
- isModal && /* @__PURE__ */ jsx4(
11293
- Modal,
11294
- {
11295
- title: title || "Detalles",
11296
- isOpen: !!context.modals[modalId],
11297
- onClose: () => context.setModals((prev) => ({ ...prev, [modalId]: false })),
11298
- children: /* @__PURE__ */ jsx4("div", { className: "prose prose-sm max-w-none", children: content })
11299
- }
11300
- )
11301
- ] });
11270
+ // vanilla/directives/admonition.ts
11271
+ var admonitionDirective = ({ directiveType, props, renderSlot }) => {
11272
+ const el = createAdmonition(directiveType, props.title, props.icon);
11273
+ if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
11274
+ if (props.style) el.setAttribute("style", props.style);
11275
+ const body = el.querySelector(".nr-admonition__body");
11276
+ if (body) {
11277
+ body.appendChild(renderSlot("default"));
11278
+ }
11279
+ return el;
11302
11280
  };
11303
- var CardDirective_default = CardDirective;
11281
+ var admonition_default = admonitionDirective;
11304
11282
 
11305
- // react/directives/DetailsDirective.tsx
11306
- import { jsx as jsx5 } from "react/jsx-runtime";
11307
- var DetailsDirective = ({
11308
- props,
11309
- renderSlot
11310
- }) => {
11311
- return /* @__PURE__ */ jsx5(
11312
- Details,
11313
- {
11314
- title: props.title || "Details",
11315
- icon: props.icon,
11316
- defaultOpen: props.defaultOpen === "true",
11317
- className: props.class,
11318
- style: props.style ? parseCssString(props.style) : void 0,
11319
- children: renderSlot("default")
11320
- }
11283
+ // vanilla/directives/details.ts
11284
+ var detailsDirective = ({ props, renderSlot }) => {
11285
+ const el = createDetails(
11286
+ props.title || "Details",
11287
+ props.icon,
11288
+ props.defaultOpen === "true"
11321
11289
  );
11290
+ if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
11291
+ if (props.style) el.setAttribute("style", props.style);
11292
+ const body = el.querySelector(".nr-details__body");
11293
+ if (body) {
11294
+ body.appendChild(renderSlot("default"));
11295
+ }
11296
+ return el;
11322
11297
  };
11323
- var DetailsDirective_default = DetailsDirective;
11298
+ var details_default = detailsDirective;
11324
11299
 
11325
- // react/directives/ModalDirective.tsx
11326
- import { useId as useId2 } from "react";
11327
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
11328
- var ModalDirective = ({
11329
- props,
11330
- renderSlot,
11331
- context
11332
- }) => {
11333
- const stableId = useId2();
11334
- const modalId = `modal-${props.id || stableId}`;
11300
+ // vanilla/directives/modal.ts
11301
+ var modalDirective = ({ props, renderSlot }) => {
11335
11302
  const label = props.label || props.title || "Open";
11336
11303
  const modalTitle = props.title || "Modal";
11337
11304
  const customClass = props.class || "";
11338
- const hasSizeClass = /\btext-(xs|sm|base|lg|xl|[2-9]xl)\b/.test(customClass);
11339
- const sizeClass = hasSizeClass ? "" : "text-sm";
11340
- const hasDisplayClass = /\b(flex|inline-flex|block|inline-block|grid|inline-grid|hidden)\b/.test(customClass);
11341
- const displayClass = hasDisplayClass ? "" : "inline-flex";
11342
- const isInlineFlex = /\binline-flex\b/.test(customClass);
11343
- const marginClass = isInlineFlex ? "my-1 mx-1" : "my-4";
11344
- const btnBase = `${displayClass} items-center w-fit ${marginClass} ${sizeClass} px-4 py-2 rounded-xl font-bold no-underline gap-2 transition-all hover:scale-105 active:scale-95 border border-border bg-background-primary/5 hover:bg-background-primary/10 text-text-primary hover:text-text-primary`.replace(/\s+/g, " ");
11345
- const btnClass = `${btnBase} ${customClass}`.trim();
11346
- const positionMap = {
11347
- "#left": "text-left",
11348
- "#center": "text-center",
11349
- "#right": "text-right"
11350
- };
11351
- const wrapperClass = customClass.split(/\s+/).map((c) => positionMap[c] || c).join(" ");
11352
- const handleOpen = () => {
11353
- context.setModals((prev) => ({ ...prev, [modalId]: true }));
11354
- };
11355
- const handleClose = () => {
11356
- context.setModals((prev) => ({ ...prev, [modalId]: false }));
11357
- };
11358
- return /* @__PURE__ */ jsxs4("div", { className: `not-prose ${wrapperClass}`.trim(), children: [
11359
- /* @__PURE__ */ jsxs4("button", { className: btnClass, onClick: handleOpen, children: [
11360
- props.icon && /* @__PURE__ */ jsx6(IconRenderer, { iconName: props.icon }),
11361
- label
11362
- ] }),
11363
- /* @__PURE__ */ jsx6(
11364
- Modal,
11365
- {
11366
- title: modalTitle,
11367
- isOpen: !!context.modals[modalId],
11368
- onClose: handleClose,
11369
- children: renderSlot("default")
11370
- }
11371
- )
11372
- ] });
11305
+ const wrapper = document.createElement("div");
11306
+ wrapper.className = "nr-modal-trigger";
11307
+ const btn = document.createElement("button");
11308
+ btn.className = `nr-button nr-button--default`;
11309
+ if (customClass) btn.classList.add(...customClass.split(/\s+/).filter(Boolean));
11310
+ const icon = props.icon || "open_in_new";
11311
+ if (icon) btn.appendChild(createIcon(icon));
11312
+ btn.appendChild(document.createTextNode(label));
11313
+ const dialog = createModal(modalTitle);
11314
+ const body = dialog.querySelector(".nr-modal__body");
11315
+ if (body) {
11316
+ const prose = document.createElement("div");
11317
+ prose.className = "nr-prose";
11318
+ prose.appendChild(renderSlot("default"));
11319
+ body.appendChild(prose);
11320
+ }
11321
+ btn.addEventListener("click", () => {
11322
+ if (!dialog.open) {
11323
+ document.body.appendChild(dialog);
11324
+ dialog.showModal();
11325
+ dialog.addEventListener("close", () => {
11326
+ dialog.remove();
11327
+ }, { once: true });
11328
+ }
11329
+ });
11330
+ wrapper.appendChild(btn);
11331
+ wrapper.appendChild(dialog);
11332
+ return wrapper;
11373
11333
  };
11374
- var ModalDirective_default = ModalDirective;
11334
+ var modal_default = modalDirective;
11375
11335
 
11376
- // react/directives/ButtonDirective.tsx
11377
- import React4 from "react";
11378
- import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
11379
- var ButtonDirective = ({
11380
- props,
11381
- renderSlot
11382
- }) => {
11336
+ // vanilla/directives/button.ts
11337
+ var buttonDirective = ({ props, renderSlot }) => {
11383
11338
  const url = props.url || props.href || "#";
11384
11339
  const label = props.label;
11385
11340
  const icon = props.icon || "near_me";
11386
11341
  const target = props.target || "_blank";
11387
11342
  const customClass = props.class || "";
11388
- const hasSizeClass = /\btext-(xs|sm|base|lg|xl|[2-9]xl)\b/.test(customClass);
11389
- const sizeClass = hasSizeClass ? "" : "text-sm";
11390
- const hasDisplayClass = /\b(flex|inline-flex|block|inline-block|grid|inline-grid|hidden)\b/.test(customClass);
11391
- const displayClass = hasDisplayClass ? "" : "inline-flex";
11392
- const isInline = !customClass || !/\b(flex|block|grid)\b/.test(customClass) || /\binline-flex\b/.test(customClass);
11393
- const marginClass = isInline ? "my-1 mx-1" : "my-4";
11394
- const btnBase = `${displayClass} items-center w-fit ${marginClass} ${sizeClass} px-4 py-2 rounded-xl font-bold no-underline gap-2 transition-all hover:scale-105 active:scale-95 border border-border bg-background-primary/5 hover:bg-background-primary/10 text-text-primary hover:text-text-primary`.replace(/\s+/g, " ");
11395
- const btnClass = `${btnBase} ${customClass}`.trim();
11396
- const positionMap = {
11397
- "#left": "flex justify-start",
11398
- "#center": "flex justify-center",
11399
- "#right": "flex justify-end"
11400
- };
11401
- const wrapperClass = customClass.split(/\s+/).map((c) => positionMap[c] || c).join(" ");
11343
+ const wrapper = document.createElement("div");
11344
+ wrapper.className = "nr-button-wrap";
11402
11345
  if (label) {
11403
- return /* @__PURE__ */ jsx7("div", { className: `not-prose ${wrapperClass}`.trim(), children: /* @__PURE__ */ jsxs5(
11404
- "a",
11405
- {
11406
- href: url,
11407
- target,
11408
- rel: "noopener noreferrer",
11409
- className: btnClass,
11410
- children: [
11411
- /* @__PURE__ */ jsx7(IconRenderer, { iconName: icon }),
11412
- label
11413
- ]
11414
- }
11415
- ) });
11346
+ const a = document.createElement("a");
11347
+ a.href = url;
11348
+ a.target = target;
11349
+ a.rel = "noopener noreferrer";
11350
+ a.className = "nr-button nr-button--default";
11351
+ if (customClass) a.classList.add(...customClass.split(/\s+/).filter(Boolean));
11352
+ a.appendChild(createIcon(icon));
11353
+ a.appendChild(document.createTextNode(label));
11354
+ wrapper.appendChild(a);
11355
+ return wrapper;
11416
11356
  }
11417
11357
  const slotContent = renderSlot("default");
11418
- const findLinks = (element) => {
11419
- if (!element) return [];
11420
- if (React4.isValidElement(element) && element.type === "a") {
11421
- return [element];
11422
- }
11423
- if (Array.isArray(element)) {
11424
- return element.flatMap(findLinks);
11425
- }
11426
- if (React4.isValidElement(element) && element.props.children) {
11427
- return findLinks(element.props.children);
11428
- }
11429
- return [];
11430
- };
11431
- const links = findLinks(slotContent);
11358
+ const links = slotContent.querySelectorAll("a");
11432
11359
  if (links.length > 0) {
11433
- return /* @__PURE__ */ jsx7("div", { className: `not-prose ${wrapperClass}`.trim(), children: links.map(
11434
- (link, index) => React4.cloneElement(
11435
- link,
11436
- {
11437
- key: index,
11438
- className: `${link.props.className || ""} ${btnClass}`.trim(),
11439
- target,
11440
- rel: "noopener noreferrer"
11441
- },
11442
- /* @__PURE__ */ jsxs5(Fragment, { children: [
11443
- /* @__PURE__ */ jsx7(IconRenderer, { iconName: icon }),
11444
- link.props.children
11445
- ] })
11446
- )
11447
- ) });
11360
+ links.forEach((link) => {
11361
+ link.classList.add("nr-button", "nr-button--default");
11362
+ if (customClass) link.classList.add(...customClass.split(/\s+/).filter(Boolean));
11363
+ });
11364
+ wrapper.appendChild(slotContent);
11365
+ } else {
11366
+ const a = document.createElement("a");
11367
+ a.href = url;
11368
+ a.target = target;
11369
+ a.rel = "noopener noreferrer";
11370
+ a.className = "nr-button nr-button--default";
11371
+ if (customClass) a.classList.add(...customClass.split(/\s+/).filter(Boolean));
11372
+ a.appendChild(createIcon(icon));
11373
+ a.appendChild(slotContent);
11374
+ wrapper.appendChild(a);
11448
11375
  }
11449
- return /* @__PURE__ */ jsx7("div", { className: `not-prose ${wrapperClass}`.trim(), children: /* @__PURE__ */ jsxs5("a", { href: url, target, rel: "noopener noreferrer", className: btnClass, children: [
11450
- /* @__PURE__ */ jsx7(IconRenderer, { iconName: icon }),
11451
- slotContent
11452
- ] }) });
11376
+ return wrapper;
11453
11377
  };
11454
- var ButtonDirective_default = ButtonDirective;
11378
+ var button_default = buttonDirective;
11455
11379
 
11456
- // react/directives/WrapperDirective.tsx
11457
- import { jsx as jsx8 } from "react/jsx-runtime";
11458
- var WrapperDirective = ({
11380
+ // vanilla/directives/card.ts
11381
+ var cardDirective = ({
11382
+ directiveType,
11459
11383
  props,
11460
- renderSlot
11384
+ slots,
11385
+ renderSlot,
11386
+ options
11461
11387
  }) => {
11462
- const className = props.class || "";
11463
- const id = props.id || "";
11464
- const inlineStyle = props.style ? parseCssString(props.style) : {};
11465
- const wrapperProps = {};
11466
- if (className) wrapperProps.className = className;
11467
- if (id) wrapperProps.id = id;
11468
- if (Object.keys(inlineStyle).length > 0) wrapperProps.style = inlineStyle;
11388
+ const { title, image, icon, url, target } = props;
11389
+ const customClass = props.class || "";
11390
+ const hasDescription = !!slots.description;
11391
+ const { isSingleCard } = options || {};
11392
+ const isModal = directiveType === "card-m";
11393
+ const isLink = directiveType === "card-b";
11394
+ const inlineStyles = props.style ? parseCssString(props.style) : {};
11395
+ const card = document.createElement("div");
11396
+ card.className = `nr-card${isModal || isLink ? " nr-card--interactive" : ""} ${customClass}`.trim();
11397
+ for (const [key, value] of Object.entries(inlineStyles)) {
11398
+ card.style.setProperty(key, String(value));
11399
+ }
11400
+ if (image) {
11401
+ const imgWrap = document.createElement("div");
11402
+ imgWrap.className = `nr-card__image${isSingleCard ? " nr-card__image--tall" : ""}`;
11403
+ const img = document.createElement("img");
11404
+ img.src = image;
11405
+ img.alt = title || "";
11406
+ img.className = "nr-card__img";
11407
+ imgWrap.appendChild(img);
11408
+ const gradient = document.createElement("div");
11409
+ gradient.className = "nr-card__gradient";
11410
+ imgWrap.appendChild(gradient);
11411
+ card.appendChild(imgWrap);
11412
+ }
11413
+ const body = document.createElement("div");
11414
+ body.className = `nr-card__body${image ? " nr-card__body--overlap" : ""}`;
11415
+ if (icon || title) {
11416
+ const header = document.createElement("div");
11417
+ header.className = "nr-card__header";
11418
+ if (icon) {
11419
+ const iconWrap = document.createElement("div");
11420
+ iconWrap.className = "nr-card__icon-wrap";
11421
+ iconWrap.appendChild(createIcon(icon));
11422
+ header.appendChild(iconWrap);
11423
+ }
11424
+ if (title) {
11425
+ const h3 = document.createElement("h3");
11426
+ h3.className = "nr-card__title";
11427
+ h3.textContent = title;
11428
+ header.appendChild(h3);
11429
+ }
11430
+ body.appendChild(header);
11431
+ }
11432
+ if (hasDescription) {
11433
+ const desc = document.createElement("div");
11434
+ desc.className = "nr-card__description";
11435
+ desc.appendChild(renderSlot("description"));
11436
+ body.appendChild(desc);
11437
+ }
11438
+ if (directiveType === "card") {
11439
+ const contentSlot = renderSlot("content") || renderSlot("default");
11440
+ if (contentSlot.childNodes.length > 0) {
11441
+ const contentDiv = document.createElement("div");
11442
+ contentDiv.className = "nr-card__content";
11443
+ contentDiv.appendChild(contentSlot);
11444
+ body.appendChild(contentDiv);
11445
+ }
11446
+ }
11447
+ if (isModal || isLink) {
11448
+ const action = document.createElement("div");
11449
+ action.className = "nr-card__action";
11450
+ if (isLink && url) {
11451
+ const a = document.createElement("a");
11452
+ a.href = url;
11453
+ a.target = target || "_blank";
11454
+ a.rel = "noopener noreferrer";
11455
+ a.className = "nr-card__action-link";
11456
+ a.appendChild(createIcon("open_in_new"));
11457
+ a.appendChild(document.createTextNode(" Link"));
11458
+ action.appendChild(a);
11459
+ } else if (isModal) {
11460
+ const modalBtn = document.createElement("div");
11461
+ modalBtn.className = "nr-card__action-link";
11462
+ modalBtn.appendChild(createIcon("arrow_forward"));
11463
+ modalBtn.appendChild(document.createTextNode(" Abrir"));
11464
+ action.appendChild(modalBtn);
11465
+ }
11466
+ body.appendChild(action);
11467
+ }
11468
+ card.appendChild(body);
11469
+ if (isModal) {
11470
+ const dialog = createModal(title || "Detalles");
11471
+ const modalBody = dialog.querySelector(".nr-modal__body");
11472
+ if (modalBody) {
11473
+ const prose = document.createElement("div");
11474
+ prose.className = "nr-prose";
11475
+ prose.appendChild(renderSlot("content") || renderSlot("default"));
11476
+ modalBody.appendChild(prose);
11477
+ }
11478
+ card.addEventListener("click", () => {
11479
+ if (!dialog.open) {
11480
+ document.body.appendChild(dialog);
11481
+ dialog.showModal();
11482
+ dialog.addEventListener("close", () => dialog.remove(), { once: true });
11483
+ }
11484
+ });
11485
+ const frag = document.createDocumentFragment();
11486
+ frag.appendChild(card);
11487
+ frag.appendChild(dialog);
11488
+ return frag;
11489
+ }
11490
+ if (isLink && url) {
11491
+ card.addEventListener("click", () => window.open(url, target || "_blank"));
11492
+ }
11493
+ return card;
11494
+ };
11495
+ var card_default = cardDirective;
11496
+
11497
+ // vanilla/directives/wrapper.ts
11498
+ var wrapperDirective = ({ props, renderSlot }) => {
11499
+ const el = document.createElement("div");
11500
+ el.className = "nr-wrapper";
11501
+ if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
11502
+ if (props.id) el.id = props.id;
11503
+ if (props.style) {
11504
+ const styles = parseCssString(props.style);
11505
+ for (const [key, value] of Object.entries(styles)) {
11506
+ el.style.setProperty(key, String(value));
11507
+ }
11508
+ }
11469
11509
  for (const [key, value] of Object.entries(props)) {
11470
11510
  if (key.startsWith("data-")) {
11471
- wrapperProps[key] = value;
11511
+ el.setAttribute(key, value);
11472
11512
  }
11473
11513
  }
11474
- return /* @__PURE__ */ jsx8("div", { ...wrapperProps, children: renderSlot("default") });
11514
+ el.appendChild(renderSlot("default"));
11515
+ return el;
11475
11516
  };
11476
- var WrapperDirective_default = WrapperDirective;
11517
+ var wrapper_default = wrapperDirective;
11477
11518
 
11478
- // react/directives/SlideDirective.tsx
11479
- import { useState as useState2, useEffect, useCallback, useRef as useRef2, useLayoutEffect } from "react";
11480
- import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
11519
+ // vanilla/directives/slide.ts
11481
11520
  var slideCounter = 0;
11482
- var SlideDirective = ({
11521
+ var slideDirective = ({
11483
11522
  props,
11484
- context,
11485
- slots
11523
+ slots,
11524
+ renderInline: renderInline2,
11525
+ renderMarkdown
11486
11526
  }) => {
11487
11527
  const rawContent = slots.default || "";
11488
11528
  const lines = rawContent.split("\n").map((l) => l.trim()).filter(Boolean);
11489
- const elements = lines.map((line) => context.parseMarkdown(line));
11490
- const [current, setCurrent] = useState2(0);
11529
+ if (lines.length === 0) {
11530
+ return document.createDocumentFragment();
11531
+ }
11491
11532
  const interval = parseInt(props.interval || "3000", 10);
11492
11533
  const speed = parseInt(props.speed || "500", 10);
11493
- const elRefs = useRef2([]);
11494
- const [maxH, setMaxH] = useState2(0);
11495
- useLayoutEffect(() => {
11496
- let h = 0;
11497
- elRefs.current.forEach((el) => {
11498
- if (el) h = Math.max(h, el.offsetHeight);
11499
- });
11500
- if (h > 0) setMaxH(h);
11501
- }, [elements]);
11502
- const cycle = useCallback(() => {
11503
- if (elements.length <= 1) return;
11504
- setCurrent((prev) => (prev + 1) % elements.length);
11505
- }, [elements.length]);
11506
- useEffect(() => {
11507
- if (elements.length <= 1) return;
11508
- const id = setInterval(cycle, interval);
11509
- return () => clearInterval(id);
11510
- }, [cycle, interval, elements.length]);
11511
- if (elements.length === 0) return null;
11512
11534
  const rawClass = props.class || "";
11513
11535
  const inlineStyle = props.style ? parseCssString(props.style) : {};
11514
- const textSizeMap = {
11515
- "text-xs": "0.75rem",
11516
- "text-sm": "0.875rem",
11517
- "text-base": "1rem",
11518
- "text-lg": "1.125rem",
11519
- "text-xl": "1.25rem",
11520
- "text-2xl": "1.5rem",
11521
- "text-3xl": "1.875rem",
11522
- "text-4xl": "2.25rem",
11523
- "text-5xl": "3rem",
11524
- "text-6xl": "3.75rem",
11525
- "text-7xl": "4.5rem",
11526
- "text-8xl": "6rem",
11527
- "text-9xl": "8rem"
11528
- };
11529
- const textSizeMatch = rawClass.match(/\btext-(xs|sm|base|lg|xl|[2-9]xl)\b/);
11530
- const forcedFontSize = textSizeMatch ? textSizeMap[textSizeMatch[0]] : null;
11531
11536
  const scopeClass = `sld-${++slideCounter}`;
11532
- const className = textSizeMatch ? rawClass.replace(textSizeMatch[0], "").replace(/\s+/g, " ").trim() : rawClass;
11533
- return /* @__PURE__ */ jsxs6(
11534
- "div",
11535
- {
11536
- className: "not-prose",
11537
- style: { height: maxH || "auto", position: "relative", overflow: "hidden", ...inlineStyle },
11538
- children: [
11539
- forcedFontSize && /* @__PURE__ */ jsx9("style", { children: `.${scopeClass} * { font-size: ${forcedFontSize} !important; line-height: normal !important; }` }),
11540
- /* @__PURE__ */ jsx9(
11541
- "div",
11542
- {
11543
- style: {
11544
- position: "absolute",
11545
- left: 0,
11546
- right: 0,
11547
- top: 0,
11548
- transition: `transform ${speed}ms cubic-bezier(0.16, 1, 0.3, 1)`,
11549
- transform: `translateY(${-current * maxH}px)`
11550
- },
11551
- children: elements.map((tokens, i) => /* @__PURE__ */ jsx9(
11552
- "div",
11553
- {
11554
- ref: (el) => {
11555
- elRefs.current[i] = el;
11556
- },
11557
- style: maxH ? { height: maxH, display: "flex", alignItems: "center", overflow: "hidden" } : { display: "flex", alignItems: "center" },
11558
- children: /* @__PURE__ */ jsx9("div", { className: `${scopeClass} ${className}`, style: { width: "100%" }, children: context.processAndRenderElements(tokens) })
11559
- },
11560
- i
11561
- ))
11562
- }
11563
- )
11564
- ]
11537
+ const container = document.createElement("div");
11538
+ container.className = "nr-slide";
11539
+ Object.assign(container.style, {
11540
+ position: "relative",
11541
+ overflow: "hidden",
11542
+ ...inlineStyle
11543
+ });
11544
+ const track = document.createElement("div");
11545
+ track.className = "nr-slide__track";
11546
+ track.style.transition = `transform ${speed}ms cubic-bezier(0.16, 1, 0.3, 1)`;
11547
+ const slideEls = [];
11548
+ for (const line of lines) {
11549
+ const slideEl = document.createElement("div");
11550
+ slideEl.className = `nr-slide__item ${scopeClass} ${rawClass}`.trim();
11551
+ slideEl.style.display = "flex";
11552
+ slideEl.style.alignItems = "center";
11553
+ if (renderMarkdown) {
11554
+ const tokens = renderMarkdown(line);
11555
+ slideEl.appendChild(tokens);
11556
+ } else if (renderInline2) {
11557
+ slideEl.appendChild(renderInline2(line));
11565
11558
  }
11566
- );
11559
+ track.appendChild(slideEl);
11560
+ slideEls.push(slideEl);
11561
+ }
11562
+ container.appendChild(track);
11563
+ let current = 0;
11564
+ let maxH = 0;
11565
+ const measureAndSetHeight = () => {
11566
+ maxH = 0;
11567
+ for (const el of slideEls) {
11568
+ maxH = Math.max(maxH, el.offsetHeight);
11569
+ }
11570
+ if (maxH > 0) {
11571
+ container.style.height = `${maxH}px`;
11572
+ for (const el of slideEls) {
11573
+ el.style.height = `${maxH}px`;
11574
+ }
11575
+ }
11576
+ };
11577
+ requestAnimationFrame(() => {
11578
+ measureAndSetHeight();
11579
+ if (document.fonts?.ready) {
11580
+ document.fonts.ready.then(measureAndSetHeight);
11581
+ }
11582
+ });
11583
+ if (lines.length > 1) {
11584
+ setInterval(() => {
11585
+ current = (current + 1) % lines.length;
11586
+ track.style.transform = `translateY(${-current * maxH}px)`;
11587
+ }, interval);
11588
+ }
11589
+ return container;
11567
11590
  };
11568
- var SlideDirective_default = SlideDirective;
11591
+ var slide_default = slideDirective;
11569
11592
 
11570
- // react/directives/index.ts
11593
+ // vanilla/directives/index.ts
11571
11594
  var directiveRegistry = {
11572
11595
  // Admonitions
11573
- note: AdmonitionDirective_default,
11574
- info: AdmonitionDirective_default,
11575
- warning: AdmonitionDirective_default,
11576
- danger: AdmonitionDirective_default,
11577
- greentext: AdmonitionDirective_default,
11596
+ note: admonition_default,
11597
+ info: admonition_default,
11598
+ warning: admonition_default,
11599
+ danger: admonition_default,
11600
+ greentext: admonition_default,
11578
11601
  // Cards
11579
- card: CardDirective_default,
11580
- "card-m": CardDirective_default,
11581
- "card-b": CardDirective_default,
11602
+ card: card_default,
11603
+ "card-m": card_default,
11604
+ "card-b": card_default,
11582
11605
  // Interactive
11583
- details: DetailsDirective_default,
11584
- modal: ModalDirective_default,
11585
- button: ButtonDirective_default,
11606
+ details: details_default,
11607
+ modal: modal_default,
11608
+ button: button_default,
11586
11609
  // Layout / generic wrappers
11587
- div: WrapperDirective_default,
11588
- style: WrapperDirective_default,
11589
- custom: WrapperDirective_default,
11590
- raw: WrapperDirective_default,
11610
+ div: wrapper_default,
11611
+ style: wrapper_default,
11612
+ custom: wrapper_default,
11613
+ raw: wrapper_default,
11591
11614
  // Animation
11592
- slide: SlideDirective_default
11615
+ slide: slide_default
11593
11616
  };
11594
11617
  var directives_default = directiveRegistry;
11595
11618
 
11596
- // react/DirectiveRenderer.tsx
11597
- import { jsx as jsx10 } from "react/jsx-runtime";
11598
- var DirectiveRenderer = ({
11599
- element,
11600
- context,
11601
- index,
11602
- allElements
11603
- }) => {
11619
+ // vanilla/renderer.ts
11620
+ function renderTokens(tokens) {
11621
+ const article = document.createElement("article");
11622
+ article.className = "nr-prose";
11623
+ const ctx = {
11624
+ parseMarkdown,
11625
+ renderElements: (tks) => renderTokensInner(tks, ctx),
11626
+ renderInline,
11627
+ renderMarkdown: (md) => renderTokensInner(parseMarkdown(md), ctx)
11628
+ };
11629
+ article.appendChild(processElements(tokens, ctx, tokens));
11630
+ return article;
11631
+ }
11632
+ function renderMarkdownString(markdown2) {
11633
+ const tokens = parseMarkdown(markdown2);
11634
+ return renderTokens(tokens);
11635
+ }
11636
+ function renderHtmlString(html) {
11637
+ let processedContent = html;
11638
+ processedContent = processedContent.replace(
11639
+ /<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
11640
+ (_match, cssContent) => {
11641
+ const styleEl = document.createElement("style");
11642
+ styleEl.setAttribute("data-nr-global", "");
11643
+ styleEl.textContent = cssContent;
11644
+ document.head.appendChild(styleEl);
11645
+ return "";
11646
+ }
11647
+ );
11648
+ const wrapper = document.createElement("div");
11649
+ wrapper.className = "nr-raw-html";
11650
+ wrapper.innerHTML = processedContent;
11651
+ const scripts = wrapper.querySelectorAll("script");
11652
+ scripts.forEach((oldScript) => {
11653
+ const newScript = document.createElement("script");
11654
+ Array.from(oldScript.attributes).forEach(
11655
+ (attr) => newScript.setAttribute(attr.name, attr.value)
11656
+ );
11657
+ newScript.textContent = oldScript.textContent;
11658
+ oldScript.parentNode?.replaceChild(newScript, oldScript);
11659
+ });
11660
+ return wrapper;
11661
+ }
11662
+ function renderTokensInner(tokens, ctx) {
11663
+ const container = document.createElement("div");
11664
+ container.appendChild(processElements(tokens, ctx, tokens));
11665
+ return container;
11666
+ }
11667
+ function processElements(elements, ctx, allElements) {
11668
+ const fragment = document.createDocumentFragment();
11669
+ let i = 0;
11670
+ while (i < elements.length) {
11671
+ const el = elements[i];
11672
+ if (el.type === "directive" && ["card", "card-m", "card-b"].includes(el.directiveType)) {
11673
+ const cards = [];
11674
+ while (i < elements.length && elements[i].type === "directive" && ["card", "card-m", "card-b"].includes(elements[i].directiveType)) {
11675
+ cards.push(elements[i]);
11676
+ i++;
11677
+ }
11678
+ if (cards.length === 1 || cards[0].props?.batch === "off") {
11679
+ for (const card of cards) {
11680
+ const rendered = renderElement(card, ctx, allElements);
11681
+ if (rendered) fragment.appendChild(rendered);
11682
+ }
11683
+ } else {
11684
+ const grid = document.createElement("div");
11685
+ grid.className = "nr-card-grid";
11686
+ for (const card of cards) {
11687
+ const rendered = renderElement(card, ctx, allElements);
11688
+ if (rendered) grid.appendChild(rendered);
11689
+ }
11690
+ fragment.appendChild(grid);
11691
+ }
11692
+ } else {
11693
+ const rendered = renderElement(el, ctx, allElements);
11694
+ if (rendered) fragment.appendChild(rendered);
11695
+ i++;
11696
+ }
11697
+ }
11698
+ return fragment;
11699
+ }
11700
+ function renderElement(element, ctx, allElements) {
11701
+ switch (element.type) {
11702
+ case "header": {
11703
+ const tag = `h${element.level}`;
11704
+ let text = element.text;
11705
+ const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
11706
+ const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
11707
+ if (alignCenter) text = alignCenter[1];
11708
+ else if (alignRight) text = alignRight[1];
11709
+ const h = document.createElement(tag);
11710
+ h.id = element.id;
11711
+ let cls = `md-h${element.level}`;
11712
+ if (alignCenter) cls += " text-center";
11713
+ if (alignRight) cls += " text-right";
11714
+ if (element.classes) cls += ` ${element.classes}`;
11715
+ h.className = cls;
11716
+ h.appendChild(renderInline(text));
11717
+ return h;
11718
+ }
11719
+ case "paragraph": {
11720
+ const p = document.createElement("p");
11721
+ let cls = "md-p";
11722
+ if (element.classes) cls += ` ${element.classes}`;
11723
+ if (element.align) cls += ` text-${element.align}`;
11724
+ p.className = cls;
11725
+ if (element.id) p.id = element.id;
11726
+ const lines = element.content.split("\n");
11727
+ for (let li = 0; li < lines.length; li++) {
11728
+ const line = lines[li];
11729
+ const hardBreakMatch = line.match(/^(.*?)(\s{2,})$/);
11730
+ if (hardBreakMatch) {
11731
+ p.appendChild(renderInline(hardBreakMatch[1]));
11732
+ p.appendChild(document.createElement("br"));
11733
+ } else {
11734
+ p.appendChild(renderInline(line));
11735
+ if (li < lines.length - 1) {
11736
+ p.appendChild(document.createTextNode(" "));
11737
+ }
11738
+ }
11739
+ }
11740
+ return p;
11741
+ }
11742
+ case "codeblock":
11743
+ return createCodeBlock(element.content, element.language, element.title);
11744
+ case "directive":
11745
+ return renderDirective(element, ctx, allElements);
11746
+ case "html": {
11747
+ const el = element;
11748
+ return renderHtmlString(el.content);
11749
+ }
11750
+ case "html-block": {
11751
+ const htmlBlock = element;
11752
+ const rawProps = parseHtmlAttrs(htmlBlock.attrs);
11753
+ const el = document.createElement(htmlBlock.tag);
11754
+ for (const [key, value] of Object.entries(rawProps)) {
11755
+ if (key === "style" && typeof value === "object") {
11756
+ for (const [prop, val] of Object.entries(value)) {
11757
+ el.style.setProperty(prop, String(val));
11758
+ }
11759
+ } else if (value === true) {
11760
+ el.setAttribute(key, "");
11761
+ } else {
11762
+ el.setAttribute(key, String(value));
11763
+ }
11764
+ }
11765
+ const childFrag = processElements(htmlBlock.children, ctx, allElements);
11766
+ el.appendChild(childFrag);
11767
+ return el;
11768
+ }
11769
+ case "image": {
11770
+ const img = document.createElement("img");
11771
+ img.src = element.src;
11772
+ img.alt = element.alt;
11773
+ img.className = "nr-image";
11774
+ if (element.style) {
11775
+ for (const [key, value] of Object.entries(element.style)) {
11776
+ img.style.setProperty(key, String(value));
11777
+ }
11778
+ }
11779
+ return img;
11780
+ }
11781
+ case "table":
11782
+ return createTable(element.content, renderInline);
11783
+ case "list":
11784
+ return createList(element.content, renderInline);
11785
+ case "blockquote":
11786
+ return createBlockquote(element.content, element.classes, renderInline);
11787
+ case "hr": {
11788
+ const hr = document.createElement("hr");
11789
+ hr.className = "nr-hr";
11790
+ return hr;
11791
+ }
11792
+ case "toc": {
11793
+ const headers = allElements.filter((e) => e.type === "header");
11794
+ return createTOC(headers.map((h) => ({ level: h.level, text: h.text, id: h.id })), renderInline);
11795
+ }
11796
+ default:
11797
+ return null;
11798
+ }
11799
+ }
11800
+ function renderDirective(element, ctx, allElements) {
11604
11801
  const { directiveType, props, slots, scopeId } = element;
11605
- const Component = directives_default[directiveType];
11802
+ const renderer = directives_default[directiveType];
11606
11803
  const renderSlot = (name) => {
11804
+ const frag = document.createDocumentFragment();
11607
11805
  const slotContent = slots[name];
11608
- if (!slotContent) return null;
11609
- const parsed = context.parseMarkdown(slotContent);
11610
- return context.processAndRenderElements(parsed);
11806
+ if (!slotContent) return frag;
11807
+ const tokens = ctx.parseMarkdown(slotContent);
11808
+ frag.appendChild(ctx.renderElements(tokens));
11809
+ return frag;
11611
11810
  };
11612
11811
  const directiveProps = {
11613
11812
  directiveType,
11614
11813
  props,
11615
11814
  slots,
11616
11815
  renderSlot,
11617
- context,
11618
- index,
11619
- allElements
11816
+ context: ctx,
11817
+ index: 0,
11818
+ allElements,
11819
+ renderInline,
11820
+ renderMarkdown: ctx.renderMarkdown
11620
11821
  };
11621
- if (Component) {
11622
- return /* @__PURE__ */ jsx10(Component, { ...directiveProps }, index);
11822
+ if (renderer) {
11823
+ return renderer(directiveProps);
11623
11824
  }
11624
- return /* @__PURE__ */ jsx10("div", { className: `my-4 p-4 rounded-2xl border border-border bg-background-primary/5`, children: renderSlot("default") }, index);
11625
- };
11626
- var DirectiveRenderer_default = DirectiveRenderer;
11825
+ const fallback = document.createElement("div");
11826
+ fallback.className = "nr-unknown-directive";
11827
+ fallback.appendChild(renderSlot("default"));
11828
+ return fallback;
11829
+ }
11627
11830
 
11628
- // react/RawHtmlRenderer.tsx
11629
- import { useRef as useRef4, useEffect as useEffect3 } from "react";
11831
+ // react/useTailwindCDN.ts
11832
+ import { useEffect, useRef } from "react";
11833
+
11834
+ // vanilla/tailwindTheme.ts
11835
+ var THEME_STYLE_ID = "nr-tailwind-theme";
11836
+ var NR_THEME_CSS = `
11837
+ @theme {
11838
+ --color-primary: var(--color-accent-primary, oklch(var(--p, 55% 0.3 240) / 1));
11839
+ --color-primary-content: #ffffff;
11840
+ --color-secondary: oklch(var(--s, 55% 0.25 200) / 1);
11841
+ --color-secondary-content: #ffffff;
11842
+ --color-accent: var(--color-accent-primary, oklch(var(--a, 65% 0.25 160) / 1));
11843
+ --color-accent-content: #ffffff;
11844
+ --color-neutral: oklch(var(--n, 50% 0.05 240) / 1);
11845
+ --color-neutral-content: var(--color-text-primary, oklch(var(--nc, 92% 0.02 240) / 1));
11846
+ --color-base-100: var(--color-background-primary, oklch(var(--b1, 15% 0.01 260) / 1));
11847
+ --color-base-200: var(--color-background-secondary-solid, oklch(var(--b2, 20% 0.02 260) / 1));
11848
+ --color-base-300: var(--color-border, oklch(var(--b3, 25% 0.03 260) / 1));
11849
+ --color-base-content: var(--color-text-primary, oklch(var(--bc, 92% 0.02 260) / 1));
11850
+ --color-info: oklch(var(--in, 70% 0.2 220) / 1);
11851
+ --color-info-content: #ffffff;
11852
+ --color-success: oklch(var(--su, 65% 0.25 140) / 1);
11853
+ --color-success-content: #ffffff;
11854
+ --color-warning: oklch(var(--wa, 80% 0.25 80) / 1);
11855
+ --color-warning-content: #1f2937;
11856
+ --color-error: oklch(var(--er, 65% 0.3 30) / 1);
11857
+ --color-error-content: #ffffff;
11858
+ }
11859
+ `;
11860
+ function getVar(root, name) {
11861
+ return getComputedStyle(root).getPropertyValue(name).trim();
11862
+ }
11863
+ function stylesheetHasTheme() {
11864
+ for (const sheet of Array.from(document.styleSheets)) {
11865
+ let rules = null;
11866
+ try {
11867
+ rules = sheet.cssRules;
11868
+ } catch {
11869
+ continue;
11870
+ }
11871
+ if (!rules) continue;
11872
+ for (const rule of Array.from(rules)) {
11873
+ const css2 = rule.cssText || "";
11874
+ if (css2.includes("@theme") || css2.includes('@plugin "daisyui"')) return true;
11875
+ }
11876
+ }
11877
+ return false;
11878
+ }
11879
+ function hasHostTheme() {
11880
+ if (typeof window === "undefined" || typeof document === "undefined") return true;
11881
+ if (getVar(document.documentElement, "--color-primary")) return true;
11882
+ if (getVar(document.documentElement, "--color-base-100")) return true;
11883
+ if (document.body && (getVar(document.body, "--color-primary") || getVar(document.body, "--color-base-100"))) return true;
11884
+ return stylesheetHasTheme();
11885
+ }
11886
+ function injectNRTailwindTheme() {
11887
+ if (typeof document === "undefined") return;
11888
+ if (document.getElementById(THEME_STYLE_ID)) return;
11889
+ if (hasHostTheme()) return;
11890
+ const style = document.createElement("style");
11891
+ style.id = THEME_STYLE_ID;
11892
+ style.setAttribute("type", "text/tailwindcss");
11893
+ style.textContent = NR_THEME_CSS;
11894
+ document.head.appendChild(style);
11895
+ }
11896
+ function removeNRTailwindTheme() {
11897
+ if (typeof document === "undefined") return;
11898
+ document.getElementById(THEME_STYLE_ID)?.remove();
11899
+ }
11630
11900
 
11631
11901
  // react/useTailwindCDN.ts
11632
- import { useEffect as useEffect2, useRef as useRef3 } from "react";
11633
11902
  var CDN_URL = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
11634
11903
  var SCRIPT_ID = "tailwind-cdn-v4-runtime";
11635
11904
  var CONFIG_ID = "tailwind-cdn-v4-config";
@@ -11642,13 +11911,14 @@ window.tailwind.config = {
11642
11911
  };
11643
11912
  `;
11644
11913
  function useLazyTailwindCDN(enabled) {
11645
- const loadedRef = useRef3(false);
11646
- useEffect2(() => {
11914
+ const loadedRef = useRef(false);
11915
+ useEffect(() => {
11647
11916
  if (!enabled) {
11648
11917
  window.__twCDNRefs = (window.__twCDNRefs ?? 1) - 1;
11649
11918
  if ((window.__twCDNRefs ?? 0) <= 0) {
11650
11919
  document.getElementById(SCRIPT_ID)?.remove();
11651
11920
  document.getElementById(CONFIG_ID)?.remove();
11921
+ removeNRTailwindTheme();
11652
11922
  window.__twCDNRefs = 0;
11653
11923
  loadedRef.current = false;
11654
11924
  }
@@ -11661,6 +11931,7 @@ function useLazyTailwindCDN(enabled) {
11661
11931
  configScript.textContent = TAILWIND_CDN_CONFIG;
11662
11932
  document.head.appendChild(configScript);
11663
11933
  }
11934
+ injectNRTailwindTheme();
11664
11935
  if (!document.getElementById(SCRIPT_ID)) {
11665
11936
  const script = document.createElement("script");
11666
11937
  script.id = SCRIPT_ID;
@@ -11673,6 +11944,7 @@ function useLazyTailwindCDN(enabled) {
11673
11944
  if ((window.__twCDNRefs ?? 0) <= 0) {
11674
11945
  document.getElementById(SCRIPT_ID)?.remove();
11675
11946
  document.getElementById(CONFIG_ID)?.remove();
11947
+ removeNRTailwindTheme();
11676
11948
  window.__twCDNRefs = 0;
11677
11949
  loadedRef.current = false;
11678
11950
  }
@@ -11693,6 +11965,7 @@ function preloadTailwindCDN() {
11693
11965
  configScript.textContent = TAILWIND_CDN_CONFIG;
11694
11966
  document.head.appendChild(configScript);
11695
11967
  }
11968
+ injectNRTailwindTheme();
11696
11969
  const script = document.createElement("script");
11697
11970
  script.id = SCRIPT_ID;
11698
11971
  script.src = CDN_URL;
@@ -11706,272 +11979,52 @@ function preloadTailwindCDN() {
11706
11979
  }
11707
11980
  }
11708
11981
 
11709
- // react/RawHtmlRenderer.tsx
11710
- import { jsx as jsx11 } from "react/jsx-runtime";
11711
- var RawHtmlRenderer = ({
11712
- content,
11713
- globalStyles,
11714
- wrapperClassName
11715
- }) => {
11716
- const containerRef = useRef4(null);
11717
- useEffect3(() => {
11718
- if (!containerRef.current) return;
11719
- const scripts = containerRef.current.querySelectorAll("script");
11720
- scripts.forEach((oldScript) => {
11721
- const newScript = document.createElement("script");
11722
- Array.from(oldScript.attributes).forEach(
11723
- (attr) => newScript.setAttribute(attr.name, attr.value)
11724
- );
11725
- newScript.textContent = oldScript.textContent;
11726
- oldScript.parentNode?.replaceChild(newScript, oldScript);
11727
- });
11728
- scanTailwindCDN();
11729
- }, [content]);
11730
- useEffect3(() => {
11731
- if (!globalStyles) return;
11732
- const styleEl = document.createElement("style");
11733
- styleEl.setAttribute("data-global", "");
11734
- styleEl.textContent = globalStyles;
11735
- document.head.appendChild(styleEl);
11736
- return () => {
11737
- if (styleEl.parentNode) document.head.removeChild(styleEl);
11738
- };
11739
- }, [globalStyles]);
11740
- return /* @__PURE__ */ jsx11("div", { className: wrapperClassName, ref: containerRef, children: /* @__PURE__ */ jsx11("div", { dangerouslySetInnerHTML: { __html: content } }) });
11741
- };
11742
- var RawHtmlRenderer_default = RawHtmlRenderer;
11743
-
11744
- // react/context.tsx
11745
- import { createContext, useContext } from "react";
11746
- var RenderCtx = createContext(null);
11747
- var RenderContextProvider = RenderCtx.Provider;
11748
-
11749
11982
  // react/CustomMarkdownRenderer.tsx
11750
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
11751
- var CustomMarkdownRenderer = ({ content: initialContent }) => {
11752
- const [modals, setModals] = useState3({});
11753
- const baseId = useId3().replace(/:/g, "");
11754
- const articleClass = `scope-${baseId}`;
11755
- const contextRef = useRef5(null);
11756
- resetScopeCounter();
11757
- const allElements = useMemo(() => parseMarkdown(initialContent), [initialContent]);
11758
- useEffect4(() => {
11983
+ import { jsx } from "react/jsx-runtime";
11984
+ var CustomMarkdownRenderer = ({ content }) => {
11985
+ const containerRef = useRef2(null);
11986
+ useEffect2(() => {
11987
+ const container = containerRef.current;
11988
+ if (!container) return;
11989
+ container.replaceChildren();
11990
+ container.appendChild(renderMarkdownString(content));
11991
+ scanTailwindCDN();
11759
11992
  const handleHashChange = () => {
11760
11993
  const hash = window.location.hash;
11761
11994
  if (hash) {
11762
11995
  const parts = hash.split("#");
11763
- const id = parts[parts.length - 1];
11764
- scrollToId(id);
11996
+ scrollToId(parts[parts.length - 1]);
11765
11997
  }
11766
11998
  };
11767
11999
  handleHashChange();
11768
12000
  window.addEventListener("hashchange", handleHashChange);
11769
12001
  return () => window.removeEventListener("hashchange", handleHashChange);
11770
- }, [initialContent]);
11771
- const renderElement = useCallback2(
11772
- (element, index, _depth = 0) => {
11773
- switch (element.type) {
11774
- case "header": {
11775
- const HeaderTag = `h${element.level}`;
11776
- let text = element.text;
11777
- const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
11778
- const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
11779
- if (alignCenter) {
11780
- text = alignCenter[1];
11781
- } else if (alignRight) {
11782
- text = alignRight[1];
11783
- }
11784
- const userClasses = element.classes || "";
11785
- let headerClasses = `md-h${element.level}`;
11786
- if (alignCenter) headerClasses += " text-center";
11787
- if (alignRight) headerClasses += " text-right";
11788
- if (userClasses) headerClasses += ` ${userClasses}`;
11789
- return React8.createElement(
11790
- HeaderTag,
11791
- { key: index, id: element.id, className: headerClasses },
11792
- renderInline(text)
11793
- );
11794
- }
11795
- case "paragraph": {
11796
- const lines = element.content.split("\n");
11797
- const processedContent = lines.map((line, lineIndex) => {
11798
- const hardBreakMatch = line.match(/^(.*?)(\s{2,})$/);
11799
- if (hardBreakMatch) {
11800
- return /* @__PURE__ */ jsxs7(React8.Fragment, { children: [
11801
- renderInline(hardBreakMatch[1]),
11802
- /* @__PURE__ */ jsx12("br", {})
11803
- ] }, lineIndex);
11804
- }
11805
- const isLastLine = lineIndex === lines.length - 1;
11806
- return /* @__PURE__ */ jsxs7(React8.Fragment, { children: [
11807
- renderInline(line),
11808
- !isLastLine && " "
11809
- ] }, lineIndex);
11810
- });
11811
- const pUserClasses = element.classes || "";
11812
- let pClasses = "md-p";
11813
- if (pUserClasses) pClasses += ` ${pUserClasses}`;
11814
- if (element.align) pClasses += ` text-${element.align}`;
11815
- return /* @__PURE__ */ jsx12("p", { id: element.id, className: pClasses, children: processedContent }, index);
11816
- }
11817
- case "codeblock":
11818
- return /* @__PURE__ */ jsx12(
11819
- CodeBlock,
11820
- {
11821
- code: element.content,
11822
- language: element.language,
11823
- title: element.title
11824
- },
11825
- index
11826
- );
11827
- case "directive":
11828
- return /* @__PURE__ */ jsx12(
11829
- DirectiveRenderer_default,
11830
- {
11831
- element,
11832
- context: contextRef.current,
11833
- index,
11834
- allElements
11835
- },
11836
- index
11837
- );
11838
- case "html": {
11839
- let processedContent = element.content;
11840
- let globalStyles = "";
11841
- processedContent = processedContent.replace(
11842
- /<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
11843
- (_match, cssContent) => {
11844
- globalStyles += cssContent + "\n";
11845
- return "";
11846
- }
11847
- );
11848
- const wrapperClassName = "w-full my-4";
11849
- return /* @__PURE__ */ jsx12(
11850
- RawHtmlRenderer_default,
11851
- {
11852
- content: processedContent,
11853
- globalStyles: globalStyles || void 0,
11854
- wrapperClassName
11855
- },
11856
- index
11857
- );
11858
- }
11859
- case "html-block": {
11860
- const htmlBlock = element;
11861
- const rawProps = parseHtmlAttrs(htmlBlock.attrs);
11862
- const props = {};
11863
- for (const [key, value] of Object.entries(rawProps)) {
11864
- if (key === "class") props["className"] = value;
11865
- else if (key === "for") props["htmlFor"] = value;
11866
- else if (key === "tabindex") props["tabIndex"] = value;
11867
- else props[key] = value;
11868
- }
11869
- return React8.createElement(
11870
- htmlBlock.tag,
11871
- { key: index, ...props },
11872
- ...processAndRenderElements(htmlBlock.children, _depth + 1)
11873
- );
11874
- }
11875
- case "image":
11876
- return /* @__PURE__ */ jsx12(
11877
- "img",
11878
- {
11879
- alt: element.alt,
11880
- src: element.src,
11881
- style: element.style,
11882
- className: "max-w-full h-auto"
11883
- },
11884
- index
11885
- );
11886
- case "table":
11887
- return /* @__PURE__ */ jsx12("div", { children: renderTable(element.content) }, index);
11888
- case "list":
11889
- return /* @__PURE__ */ jsx12("div", { children: renderList(element.content) }, index);
11890
- case "blockquote":
11891
- return /* @__PURE__ */ jsx12("blockquote", { className: `border-l-4 border-accent-primary/30 pl-4 italic text-text-secondary my-4 text-sm sm:text-base${element.classes ? ` ${element.classes}` : ""}`, children: renderInline(element.content) }, index);
11892
- case "hr":
11893
- return /* @__PURE__ */ jsx12("hr", { className: "my-8 border-border" }, index);
11894
- case "toc":
11895
- return /* @__PURE__ */ jsx12("div", { children: generateToc(allElements) }, index);
11896
- default:
11897
- return null;
11898
- }
11899
- },
11900
- [allElements]
11901
- );
11902
- const processAndRenderElements = useCallback2(
11903
- (elements, depth = 0) => {
11904
- const result = [];
11905
- let i = 0;
11906
- while (i < elements.length) {
11907
- const el = elements[i];
11908
- if (el.type === "directive" && ["card", "card-m", "card-b"].includes(el.directiveType)) {
11909
- const cards = [];
11910
- while (i < elements.length && elements[i].type === "directive" && ["card", "card-m", "card-b"].includes(elements[i].directiveType)) {
11911
- cards.push(elements[i]);
11912
- i++;
11913
- }
11914
- if (cards.length === 1 || cards[0].props?.batch === "off") {
11915
- for (let c = 0; c < cards.length; c++) {
11916
- result.push(renderElement(cards[c], result.length, depth));
11917
- }
11918
- } else {
11919
- const firstCardClass = cards[0].props?.["class"] || "";
11920
- const justifyClasses = firstCardClass.match(/\bjustify-\S+/g) || [];
11921
- const wrapperJustify = justifyClasses.length > 0 ? justifyClasses.join(" ") : "";
11922
- result.push(
11923
- /* @__PURE__ */ jsx12("div", { className: `not-prose flex flex-wrap gap-6 my-6 ${wrapperJustify}`, children: cards.map((card, ci) => /* @__PURE__ */ jsx12(React8.Fragment, { children: renderElement(card, ci, depth) }, ci)) }, `card-grid-${result.length}`)
11924
- );
11925
- }
11926
- } else {
11927
- result.push(renderElement(el, result.length, depth));
11928
- i++;
11929
- }
11930
- }
11931
- return result;
11932
- },
11933
- [renderElement]
11934
- );
11935
- const generateToc = (elements) => {
11936
- const headers = extractHeaders(elements);
11937
- if (headers.length === 0) return null;
11938
- return /* @__PURE__ */ jsxs7("nav", { className: "not-prose my-6 p-4 rounded-2xl border border-border bg-background-primary/5", children: [
11939
- /* @__PURE__ */ jsx12("div", { className: "text-base font-bold mb-3", children: "Table of Contents" }),
11940
- /* @__PURE__ */ jsx12("ul", { className: "space-y-1 list-none p-0 m-0", children: headers.map((h, i) => {
11941
- if (h.type !== "header") return null;
11942
- const indentClass = h.level <= 2 ? "pl-0" : h.level === 3 ? "pl-4" : h.level === 4 ? "pl-8" : "pl-12";
11943
- return /* @__PURE__ */ jsx12("li", { className: `${indentClass} text-sm sm:text-base`, children: /* @__PURE__ */ jsx12(
11944
- "a",
11945
- {
11946
- href: `#${h.id}`,
11947
- className: "text-accent-primary hover:text-accent-primary/80 no-underline hover:underline transition-colors",
11948
- onClick: (e) => {
11949
- e.preventDefault();
11950
- scrollToId(h.id);
11951
- },
11952
- children: renderInline(h.text.replace(/->|<-/g, "").trim())
11953
- }
11954
- ) }, i);
11955
- }) })
11956
- ] });
11957
- };
11958
- const contextForDirectives = {
11959
- modals,
11960
- setModals,
11961
- articleClass,
11962
- allElements,
11963
- parseMarkdown,
11964
- renderElement,
11965
- renderInline,
11966
- processAndRenderElements
11967
- };
11968
- contextRef.current = contextForDirectives;
11969
- return /* @__PURE__ */ jsx12(RenderContextProvider, { value: contextForDirectives, children: processAndRenderElements(allElements) });
12002
+ }, [content]);
12003
+ return /* @__PURE__ */ jsx("div", { ref: containerRef });
11970
12004
  };
11971
12005
  var CustomMarkdownRenderer_default = CustomMarkdownRenderer;
11972
12006
 
12007
+ // react/RawHtmlRenderer.tsx
12008
+ import { useEffect as useEffect3, useRef as useRef3 } from "react";
12009
+ import { jsx as jsx2 } from "react/jsx-runtime";
12010
+ var RawHtmlRenderer = ({
12011
+ content,
12012
+ wrapperClassName = "nr-raw-html"
12013
+ }) => {
12014
+ const containerRef = useRef3(null);
12015
+ useEffect3(() => {
12016
+ const container = containerRef.current;
12017
+ if (!container) return;
12018
+ container.replaceChildren();
12019
+ container.appendChild(renderHtmlString(content));
12020
+ scanTailwindCDN();
12021
+ }, [content]);
12022
+ return /* @__PURE__ */ jsx2("div", { ref: containerRef, className: wrapperClassName });
12023
+ };
12024
+ var RawHtmlRenderer_default = RawHtmlRenderer;
12025
+
11973
12026
  // react/NRpreviewer.tsx
11974
- import { jsx as jsx13 } from "react/jsx-runtime";
12027
+ import { jsx as jsx3 } from "react/jsx-runtime";
11975
12028
  var NRpreviewer = ({
11976
12029
  content,
11977
12030
  html,
@@ -11980,35 +12033,31 @@ var NRpreviewer = ({
11980
12033
  style
11981
12034
  }) => {
11982
12035
  useLazyTailwindCDN(tailwindCDN);
12036
+ const wrapperClass = `nr-prose${className ? ` ${className}` : ""}`;
11983
12037
  if (content) {
11984
- return /* @__PURE__ */ jsx13("div", { className: `nr-prose${className ? ` ${className}` : ""}`, style, children: /* @__PURE__ */ jsx13(CustomMarkdownRenderer_default, { content }) });
12038
+ return /* @__PURE__ */ jsx3("div", { className: wrapperClass, style, children: /* @__PURE__ */ jsx3(CustomMarkdownRenderer_default, { content }) });
11985
12039
  }
11986
12040
  if (html) {
11987
- return /* @__PURE__ */ jsx13("div", { className: `nr-prose${className ? ` ${className}` : ""}`, style, children: /* @__PURE__ */ jsx13(RawHtmlRenderer_default, { content: html, wrapperClassName: "nr-preview-html" }) });
12041
+ return /* @__PURE__ */ jsx3("div", { className: wrapperClass, style, children: /* @__PURE__ */ jsx3(RawHtmlRenderer_default, { content: html }) });
11988
12042
  }
11989
12043
  return null;
11990
12044
  };
11991
12045
  var NRpreviewer_default = NRpreviewer;
11992
12046
 
11993
12047
  // react/useDebounce.ts
11994
- import { useState as useState4, useEffect as useEffect5 } from "react";
12048
+ import { useState, useEffect as useEffect4 } from "react";
11995
12049
  function useDebounce(value, delay) {
11996
- const [debouncedValue, setDebouncedValue] = useState4(value);
11997
- useEffect5(() => {
12050
+ const [debouncedValue, setDebouncedValue] = useState(value);
12051
+ useEffect4(() => {
11998
12052
  const timer = setTimeout(() => setDebouncedValue(value), delay);
11999
12053
  return () => clearTimeout(timer);
12000
12054
  }, [value, delay]);
12001
12055
  return debouncedValue;
12002
12056
  }
12003
12057
  export {
12004
- Admonition,
12005
- CodeBlock,
12006
12058
  CustomMarkdownRenderer_default as CustomMarkdownRenderer,
12007
- Details,
12008
- IconRenderer,
12009
- Modal,
12010
12059
  NRpreviewer_default as NRpreviewer,
12011
- extractHeaders,
12060
+ RawHtmlRenderer_default as RawHtmlRenderer,
12012
12061
  parseMarkdown,
12013
12062
  preloadTailwindCDN,
12014
12063
  scanTailwindCDN,