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