@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
@@ -80,6 +80,12 @@ declare function renderTokens(tokens: Token[]): HTMLElement;
80
80
  * Convenience: parse markdown string and render directly.
81
81
  */
82
82
  declare function renderMarkdownString(markdown: string): HTMLElement;
83
+ /**
84
+ * Render a raw HTML string into a wrapper element.
85
+ * Extracts <style> blocks (injected globally into <head>) and
86
+ * force-executes any <script> tags.
87
+ */
88
+ declare function renderHtmlString(html: string): HTMLElement;
83
89
 
84
90
  /**
85
91
  * Render inline markdown text into a DocumentFragment.
@@ -90,7 +96,7 @@ declare function renderMarkdownString(markdown: string): HTMLElement;
90
96
  declare function renderInline(text: string): DocumentFragment;
91
97
 
92
98
  /**
93
- * Create a Material Symbols icon element.
99
+ * Create a Material Icons Round icon element.
94
100
  */
95
101
  declare function createIcon(iconName: string, extraClasses?: string): HTMLElement;
96
102
  /**
@@ -170,4 +176,20 @@ interface DirectiveProps {
170
176
  type DirectiveRendererFn = (props: DirectiveProps) => HTMLElement | DocumentFragment;
171
177
  declare const directiveRegistry: Record<string, DirectiveRendererFn>;
172
178
 
173
- export { type DirectiveProps, type DirectiveRendererFn, type VanillaRenderContext, createAdmonition, createBlockquote, createCodeBlock, createDetails, createIcon, createList, createModal, createTOC, createTable, directiveRegistry, renderInline, renderMarkdownString, renderTokens };
179
+ /**
180
+ * Detect whether the host page already provides a color theme
181
+ * (daisyUI, a Tailwind @theme block, or --color-* variables).
182
+ */
183
+ declare function hasHostTheme(): boolean;
184
+ /**
185
+ * Inject the NoirMD @theme block so Tailwind CDN color classes
186
+ * (bg-primary, text-secondary, ...) resolve inside markdown.
187
+ * Skipped when the host already defines a theme. Idempotent.
188
+ */
189
+ declare function injectNRTailwindTheme(): void;
190
+ /**
191
+ * Remove the injected NoirMD @theme block (idempotent).
192
+ */
193
+ declare function removeNRTailwindTheme(): void;
194
+
195
+ export { type DirectiveProps, type DirectiveRendererFn, type VanillaRenderContext, createAdmonition, createBlockquote, createCodeBlock, createDetails, createIcon, createList, createModal, createTOC, createTable, directiveRegistry, hasHostTheme, injectNRTailwindTheme, removeNRTailwindTheme, renderHtmlString, renderInline, renderMarkdownString, renderTokens };
package/dist/vanilla.d.ts CHANGED
@@ -80,6 +80,12 @@ declare function renderTokens(tokens: Token[]): HTMLElement;
80
80
  * Convenience: parse markdown string and render directly.
81
81
  */
82
82
  declare function renderMarkdownString(markdown: string): HTMLElement;
83
+ /**
84
+ * Render a raw HTML string into a wrapper element.
85
+ * Extracts <style> blocks (injected globally into <head>) and
86
+ * force-executes any <script> tags.
87
+ */
88
+ declare function renderHtmlString(html: string): HTMLElement;
83
89
 
84
90
  /**
85
91
  * Render inline markdown text into a DocumentFragment.
@@ -90,7 +96,7 @@ declare function renderMarkdownString(markdown: string): HTMLElement;
90
96
  declare function renderInline(text: string): DocumentFragment;
91
97
 
92
98
  /**
93
- * Create a Material Symbols icon element.
99
+ * Create a Material Icons Round icon element.
94
100
  */
95
101
  declare function createIcon(iconName: string, extraClasses?: string): HTMLElement;
96
102
  /**
@@ -170,4 +176,20 @@ interface DirectiveProps {
170
176
  type DirectiveRendererFn = (props: DirectiveProps) => HTMLElement | DocumentFragment;
171
177
  declare const directiveRegistry: Record<string, DirectiveRendererFn>;
172
178
 
173
- export { type DirectiveProps, type DirectiveRendererFn, type VanillaRenderContext, createAdmonition, createBlockquote, createCodeBlock, createDetails, createIcon, createList, createModal, createTOC, createTable, directiveRegistry, renderInline, renderMarkdownString, renderTokens };
179
+ /**
180
+ * Detect whether the host page already provides a color theme
181
+ * (daisyUI, a Tailwind @theme block, or --color-* variables).
182
+ */
183
+ declare function hasHostTheme(): boolean;
184
+ /**
185
+ * Inject the NoirMD @theme block so Tailwind CDN color classes
186
+ * (bg-primary, text-secondary, ...) resolve inside markdown.
187
+ * Skipped when the host already defines a theme. Idempotent.
188
+ */
189
+ declare function injectNRTailwindTheme(): void;
190
+ /**
191
+ * Remove the injected NoirMD @theme block (idempotent).
192
+ */
193
+ declare function removeNRTailwindTheme(): void;
194
+
195
+ export { type DirectiveProps, type DirectiveRendererFn, type VanillaRenderContext, createAdmonition, createBlockquote, createCodeBlock, createDetails, createIcon, createList, createModal, createTOC, createTable, directiveRegistry, hasHostTheme, injectNRTailwindTheme, removeNRTailwindTheme, renderHtmlString, renderInline, renderMarkdownString, renderTokens };
package/dist/vanilla.js CHANGED
@@ -1647,6 +1647,7 @@ function parseMarkdown(markdown2) {
1647
1647
  if (!markdown2) return [];
1648
1648
  const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
1649
1649
  const result = [];
1650
+ const usedIds = /* @__PURE__ */ new Set();
1650
1651
  let i = 0;
1651
1652
  while (i < lines.length) {
1652
1653
  const line = lines[i];
@@ -1656,7 +1657,14 @@ function parseMarkdown(markdown2) {
1656
1657
  const level = match[1].length;
1657
1658
  const rawText = match[2];
1658
1659
  const { text: text2, classes: classes2, id: customId } = extractAttributes(rawText);
1659
- const id2 = customId || generateId(text2.replace(/->|<-/g, ""));
1660
+ const baseId = customId || generateId(text2.replace(/->|<-/g, ""));
1661
+ let id2 = baseId;
1662
+ let n = 1;
1663
+ while (usedIds.has(id2)) {
1664
+ n++;
1665
+ id2 = `${baseId}-${n}`;
1666
+ }
1667
+ usedIds.add(id2);
1660
1668
  result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0 });
1661
1669
  i++;
1662
1670
  continue;
@@ -10908,7 +10916,7 @@ var highlightSetup_default = core_default;
10908
10916
  // vanilla/components.ts
10909
10917
  function createIcon(iconName, extraClasses) {
10910
10918
  const span = document.createElement("span");
10911
- const cls = `nr-icon material-symbols-rounded${extraClasses ? ` ${extraClasses}` : ""}`;
10919
+ const cls = `nr-icon material-icons-round${extraClasses ? ` ${extraClasses}` : ""}`;
10912
10920
  span.className = cls;
10913
10921
  span.setAttribute("aria-hidden", "true");
10914
10922
  const isCodepoint = /^[eE][0-9a-fA-F]{3,4}$/.test(iconName);
@@ -10970,7 +10978,7 @@ var DEFAULT_ADMONITION_ICONS = {
10970
10978
  info: "lightbulb",
10971
10979
  warning: "warning",
10972
10980
  danger: "report",
10973
- greentext: "subdirectory_play_arrow"
10981
+ greentext: "subdirectory_arrow_right"
10974
10982
  };
10975
10983
  function createAdmonition(type, title, icon) {
10976
10984
  const el = document.createElement("div");
@@ -11289,12 +11297,16 @@ var modalDirective = ({ props, renderSlot }) => {
11289
11297
  const btn = document.createElement("button");
11290
11298
  btn.className = `nr-button nr-button--default`;
11291
11299
  if (customClass) btn.classList.add(...customClass.split(/\s+/).filter(Boolean));
11292
- if (props.icon) btn.appendChild(createIcon(props.icon));
11300
+ const icon = props.icon || "open_in_new";
11301
+ if (icon) btn.appendChild(createIcon(icon));
11293
11302
  btn.appendChild(document.createTextNode(label));
11294
11303
  const dialog = createModal(modalTitle);
11295
11304
  const body = dialog.querySelector(".nr-modal__body");
11296
11305
  if (body) {
11297
- body.appendChild(renderSlot("default"));
11306
+ const prose = document.createElement("div");
11307
+ prose.className = "nr-prose";
11308
+ prose.appendChild(renderSlot("default"));
11309
+ body.appendChild(prose);
11298
11310
  }
11299
11311
  btn.addEventListener("click", () => {
11300
11312
  if (!dialog.open) {
@@ -11448,8 +11460,10 @@ var cardDirective = ({
11448
11460
  const dialog = createModal(title || "Detalles");
11449
11461
  const modalBody = dialog.querySelector(".nr-modal__body");
11450
11462
  if (modalBody) {
11451
- const contentSlot = renderSlot("content") || renderSlot("default");
11452
- modalBody.appendChild(contentSlot);
11463
+ const prose = document.createElement("div");
11464
+ prose.className = "nr-prose";
11465
+ prose.appendChild(renderSlot("content") || renderSlot("default"));
11466
+ modalBody.appendChild(prose);
11453
11467
  }
11454
11468
  card.addEventListener("click", () => {
11455
11469
  if (!dialog.open) {
@@ -11609,6 +11623,32 @@ function renderMarkdownString(markdown2) {
11609
11623
  const tokens = parseMarkdown(markdown2);
11610
11624
  return renderTokens(tokens);
11611
11625
  }
11626
+ function renderHtmlString(html) {
11627
+ let processedContent = html;
11628
+ processedContent = processedContent.replace(
11629
+ /<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
11630
+ (_match, cssContent) => {
11631
+ const styleEl = document.createElement("style");
11632
+ styleEl.setAttribute("data-nr-global", "");
11633
+ styleEl.textContent = cssContent;
11634
+ document.head.appendChild(styleEl);
11635
+ return "";
11636
+ }
11637
+ );
11638
+ const wrapper = document.createElement("div");
11639
+ wrapper.className = "nr-raw-html";
11640
+ wrapper.innerHTML = processedContent;
11641
+ const scripts = wrapper.querySelectorAll("script");
11642
+ scripts.forEach((oldScript) => {
11643
+ const newScript = document.createElement("script");
11644
+ Array.from(oldScript.attributes).forEach(
11645
+ (attr) => newScript.setAttribute(attr.name, attr.value)
11646
+ );
11647
+ newScript.textContent = oldScript.textContent;
11648
+ oldScript.parentNode?.replaceChild(newScript, oldScript);
11649
+ });
11650
+ return wrapper;
11651
+ }
11612
11652
  function renderTokensInner(tokens, ctx) {
11613
11653
  const container = document.createElement("div");
11614
11654
  container.appendChild(processElements(tokens, ctx, tokens));
@@ -11695,30 +11735,7 @@ function renderElement(element, ctx, allElements) {
11695
11735
  return renderDirective(element, ctx, allElements);
11696
11736
  case "html": {
11697
11737
  const el = element;
11698
- let processedContent = el.content;
11699
- processedContent = processedContent.replace(
11700
- /<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
11701
- (_match, cssContent) => {
11702
- const styleEl = document.createElement("style");
11703
- styleEl.setAttribute("data-nr-global", "");
11704
- styleEl.textContent = cssContent;
11705
- document.head.appendChild(styleEl);
11706
- return "";
11707
- }
11708
- );
11709
- const wrapper = document.createElement("div");
11710
- wrapper.className = "nr-raw-html";
11711
- wrapper.innerHTML = processedContent;
11712
- const scripts = wrapper.querySelectorAll("script");
11713
- scripts.forEach((oldScript) => {
11714
- const newScript = document.createElement("script");
11715
- Array.from(oldScript.attributes).forEach(
11716
- (attr) => newScript.setAttribute(attr.name, attr.value)
11717
- );
11718
- newScript.textContent = oldScript.textContent;
11719
- oldScript.parentNode?.replaceChild(newScript, oldScript);
11720
- });
11721
- return wrapper;
11738
+ return renderHtmlString(el.content);
11722
11739
  }
11723
11740
  case "html-block": {
11724
11741
  const htmlBlock = element;
@@ -11800,6 +11817,73 @@ function renderDirective(element, ctx, allElements) {
11800
11817
  fallback.appendChild(renderSlot("default"));
11801
11818
  return fallback;
11802
11819
  }
11820
+
11821
+ // vanilla/tailwindTheme.ts
11822
+ var THEME_STYLE_ID = "nr-tailwind-theme";
11823
+ var NR_THEME_CSS = `
11824
+ @theme {
11825
+ --color-primary: var(--color-accent-primary, oklch(var(--p, 55% 0.3 240) / 1));
11826
+ --color-primary-content: #ffffff;
11827
+ --color-secondary: oklch(var(--s, 55% 0.25 200) / 1);
11828
+ --color-secondary-content: #ffffff;
11829
+ --color-accent: var(--color-accent-primary, oklch(var(--a, 65% 0.25 160) / 1));
11830
+ --color-accent-content: #ffffff;
11831
+ --color-neutral: oklch(var(--n, 50% 0.05 240) / 1);
11832
+ --color-neutral-content: var(--color-text-primary, oklch(var(--nc, 92% 0.02 240) / 1));
11833
+ --color-base-100: var(--color-background-primary, oklch(var(--b1, 15% 0.01 260) / 1));
11834
+ --color-base-200: var(--color-background-secondary-solid, oklch(var(--b2, 20% 0.02 260) / 1));
11835
+ --color-base-300: var(--color-border, oklch(var(--b3, 25% 0.03 260) / 1));
11836
+ --color-base-content: var(--color-text-primary, oklch(var(--bc, 92% 0.02 260) / 1));
11837
+ --color-info: oklch(var(--in, 70% 0.2 220) / 1);
11838
+ --color-info-content: #ffffff;
11839
+ --color-success: oklch(var(--su, 65% 0.25 140) / 1);
11840
+ --color-success-content: #ffffff;
11841
+ --color-warning: oklch(var(--wa, 80% 0.25 80) / 1);
11842
+ --color-warning-content: #1f2937;
11843
+ --color-error: oklch(var(--er, 65% 0.3 30) / 1);
11844
+ --color-error-content: #ffffff;
11845
+ }
11846
+ `;
11847
+ function getVar(root, name) {
11848
+ return getComputedStyle(root).getPropertyValue(name).trim();
11849
+ }
11850
+ function stylesheetHasTheme() {
11851
+ for (const sheet of Array.from(document.styleSheets)) {
11852
+ let rules = null;
11853
+ try {
11854
+ rules = sheet.cssRules;
11855
+ } catch {
11856
+ continue;
11857
+ }
11858
+ if (!rules) continue;
11859
+ for (const rule of Array.from(rules)) {
11860
+ const css2 = rule.cssText || "";
11861
+ if (css2.includes("@theme") || css2.includes('@plugin "daisyui"')) return true;
11862
+ }
11863
+ }
11864
+ return false;
11865
+ }
11866
+ function hasHostTheme() {
11867
+ if (typeof window === "undefined" || typeof document === "undefined") return true;
11868
+ if (getVar(document.documentElement, "--color-primary")) return true;
11869
+ if (getVar(document.documentElement, "--color-base-100")) return true;
11870
+ if (document.body && (getVar(document.body, "--color-primary") || getVar(document.body, "--color-base-100"))) return true;
11871
+ return stylesheetHasTheme();
11872
+ }
11873
+ function injectNRTailwindTheme() {
11874
+ if (typeof document === "undefined") return;
11875
+ if (document.getElementById(THEME_STYLE_ID)) return;
11876
+ if (hasHostTheme()) return;
11877
+ const style = document.createElement("style");
11878
+ style.id = THEME_STYLE_ID;
11879
+ style.setAttribute("type", "text/tailwindcss");
11880
+ style.textContent = NR_THEME_CSS;
11881
+ document.head.appendChild(style);
11882
+ }
11883
+ function removeNRTailwindTheme() {
11884
+ if (typeof document === "undefined") return;
11885
+ document.getElementById(THEME_STYLE_ID)?.remove();
11886
+ }
11803
11887
  export {
11804
11888
  createAdmonition,
11805
11889
  createBlockquote,
@@ -11811,6 +11895,10 @@ export {
11811
11895
  createTOC,
11812
11896
  createTable,
11813
11897
  directives_default as directiveRegistry,
11898
+ hasHostTheme,
11899
+ injectNRTailwindTheme,
11900
+ removeNRTailwindTheme,
11901
+ renderHtmlString,
11814
11902
  renderInline,
11815
11903
  renderMarkdownString,
11816
11904
  renderTokens