@noirmd/previewer 1.1.0 → 1.2.0
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.
- package/dist/NReditor.cjs +140 -59
- package/dist/NReditor.cjs.map +1 -1
- package/dist/NReditor.d.cts +5 -0
- package/dist/NReditor.d.ts +5 -0
- package/dist/NReditor.js +125 -44
- package/dist/NReditor.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/editor.css +179 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/vanilla.cjs +1 -1
- package/dist/vanilla.cjs.map +1 -1
- package/dist/vanilla.js +1 -1
- package/dist/vanilla.js.map +1 -1
- package/dist/vue.cjs +11 -20
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +10 -4
- package/dist/vue.js.map +1 -1
- package/editor.css +179 -0
- package/package.json +5 -3
package/dist/NReditor.d.cts
CHANGED
|
@@ -10,6 +10,10 @@ interface NReditorProps extends ReactCodeMirrorProps {
|
|
|
10
10
|
debounceMs?: number;
|
|
11
11
|
/** Inject Tailwind v4 browser CDN for preview. Default: false */
|
|
12
12
|
tailwindCDN?: boolean;
|
|
13
|
+
/** Called when user clicks Guía */
|
|
14
|
+
onGuide?: () => void;
|
|
15
|
+
/** Called when user clicks Configurar */
|
|
16
|
+
onConfig?: () => void;
|
|
13
17
|
}
|
|
14
18
|
/**
|
|
15
19
|
* NReditor — CodeMirror 6 editor with live markdown preview.
|
|
@@ -18,6 +22,7 @@ interface NReditorProps extends ReactCodeMirrorProps {
|
|
|
18
22
|
* @example
|
|
19
23
|
* ```tsx
|
|
20
24
|
* import NReditor from '@noirmd/previewer/editor';
|
|
25
|
+
* import '@noirmd/previewer/editor.css';
|
|
21
26
|
* import '@noirmd/previewer/markdown.css';
|
|
22
27
|
*
|
|
23
28
|
* <NReditor value={md} onChange={setMd} />
|
package/dist/NReditor.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ interface NReditorProps extends ReactCodeMirrorProps {
|
|
|
10
10
|
debounceMs?: number;
|
|
11
11
|
/** Inject Tailwind v4 browser CDN for preview. Default: false */
|
|
12
12
|
tailwindCDN?: boolean;
|
|
13
|
+
/** Called when user clicks Guía */
|
|
14
|
+
onGuide?: () => void;
|
|
15
|
+
/** Called when user clicks Configurar */
|
|
16
|
+
onConfig?: () => void;
|
|
13
17
|
}
|
|
14
18
|
/**
|
|
15
19
|
* NReditor — CodeMirror 6 editor with live markdown preview.
|
|
@@ -18,6 +22,7 @@ interface NReditorProps extends ReactCodeMirrorProps {
|
|
|
18
22
|
* @example
|
|
19
23
|
* ```tsx
|
|
20
24
|
* import NReditor from '@noirmd/previewer/editor';
|
|
25
|
+
* import '@noirmd/previewer/editor.css';
|
|
21
26
|
* import '@noirmd/previewer/markdown.css';
|
|
22
27
|
*
|
|
23
28
|
* <NReditor value={md} onChange={setMd} />
|
package/dist/NReditor.js
CHANGED
|
@@ -313,6 +313,62 @@ function useDebounce(value, delay) {
|
|
|
313
313
|
return debouncedValue;
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
+
// react/useTailwindCDN.ts
|
|
317
|
+
import { useEffect as useEffect2, useRef } from "react";
|
|
318
|
+
var CDN_URL = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
|
|
319
|
+
var SCRIPT_ID = "tailwind-cdn-v4-runtime";
|
|
320
|
+
var CONFIG_ID = "tailwind-cdn-v4-config";
|
|
321
|
+
var TAILWIND_CDN_CONFIG = `
|
|
322
|
+
window.tailwind = window.tailwind || {};
|
|
323
|
+
window.tailwind.config = {
|
|
324
|
+
corePlugins: {
|
|
325
|
+
preflight: false,
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
`;
|
|
329
|
+
function useLazyTailwindCDN(enabled) {
|
|
330
|
+
const loadedRef = useRef(false);
|
|
331
|
+
useEffect2(() => {
|
|
332
|
+
if (!enabled) {
|
|
333
|
+
window.__twCDNRefs = (window.__twCDNRefs ?? 1) - 1;
|
|
334
|
+
if ((window.__twCDNRefs ?? 0) <= 0) {
|
|
335
|
+
document.getElementById(SCRIPT_ID)?.remove();
|
|
336
|
+
document.getElementById(CONFIG_ID)?.remove();
|
|
337
|
+
window.__twCDNRefs = 0;
|
|
338
|
+
loadedRef.current = false;
|
|
339
|
+
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
window.__twCDNRefs = (window.__twCDNRefs ?? 0) + 1;
|
|
343
|
+
if (!document.getElementById(CONFIG_ID)) {
|
|
344
|
+
const configScript = document.createElement("script");
|
|
345
|
+
configScript.id = CONFIG_ID;
|
|
346
|
+
configScript.textContent = TAILWIND_CDN_CONFIG;
|
|
347
|
+
document.head.appendChild(configScript);
|
|
348
|
+
}
|
|
349
|
+
if (!document.getElementById(SCRIPT_ID)) {
|
|
350
|
+
const script = document.createElement("script");
|
|
351
|
+
script.id = SCRIPT_ID;
|
|
352
|
+
script.src = CDN_URL;
|
|
353
|
+
document.head.appendChild(script);
|
|
354
|
+
loadedRef.current = true;
|
|
355
|
+
}
|
|
356
|
+
return () => {
|
|
357
|
+
window.__twCDNRefs = (window.__twCDNRefs ?? 1) - 1;
|
|
358
|
+
if ((window.__twCDNRefs ?? 0) <= 0) {
|
|
359
|
+
document.getElementById(SCRIPT_ID)?.remove();
|
|
360
|
+
document.getElementById(CONFIG_ID)?.remove();
|
|
361
|
+
window.__twCDNRefs = 0;
|
|
362
|
+
loadedRef.current = false;
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
}, [enabled]);
|
|
366
|
+
}
|
|
367
|
+
function scanTailwindCDN() {
|
|
368
|
+
const tw = window.tailwind;
|
|
369
|
+
if (tw?.scan) tw.scan();
|
|
370
|
+
}
|
|
371
|
+
|
|
316
372
|
// react/CustomMarkdownRenderer.tsx
|
|
317
373
|
import React8, { useState as useState4, useEffect as useEffect5, useCallback as useCallback2, useMemo, useId as useId3, useRef as useRef5 } from "react";
|
|
318
374
|
|
|
@@ -408,7 +464,7 @@ function parseHtmlAttrs(attrsString) {
|
|
|
408
464
|
// core/parser.ts
|
|
409
465
|
function parseMarkdown(markdown2) {
|
|
410
466
|
if (!markdown2) return [];
|
|
411
|
-
const lines = markdown2.split("\n");
|
|
467
|
+
const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
|
|
412
468
|
const result = [];
|
|
413
469
|
let i = 0;
|
|
414
470
|
while (i < lines.length) {
|
|
@@ -735,7 +791,7 @@ function splitSlots(rawContent) {
|
|
|
735
791
|
}
|
|
736
792
|
|
|
737
793
|
// react/ui-components.tsx
|
|
738
|
-
import { useState as useState2, useRef } from "react";
|
|
794
|
+
import { useState as useState2, useRef as useRef2 } from "react";
|
|
739
795
|
|
|
740
796
|
// react/highlightSetup.ts
|
|
741
797
|
import hljs from "highlight.js/lib/core";
|
|
@@ -828,7 +884,7 @@ var IconRenderer = ({ iconName, extraClasses = "" }) => {
|
|
|
828
884
|
};
|
|
829
885
|
var CodeBlock = ({ code, language, title }) => {
|
|
830
886
|
const [copied, setCopied] = useState2(false);
|
|
831
|
-
const timerRef =
|
|
887
|
+
const timerRef = useRef2(null);
|
|
832
888
|
const lang = language?.split(/[\s{]/)[0]?.trim() || "";
|
|
833
889
|
let html;
|
|
834
890
|
try {
|
|
@@ -1355,7 +1411,7 @@ var WrapperDirective = ({
|
|
|
1355
1411
|
var WrapperDirective_default = WrapperDirective;
|
|
1356
1412
|
|
|
1357
1413
|
// react/directives/SlideDirective.tsx
|
|
1358
|
-
import { useState as useState3, useEffect as
|
|
1414
|
+
import { useState as useState3, useEffect as useEffect3, useCallback, useRef as useRef3, useLayoutEffect } from "react";
|
|
1359
1415
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1360
1416
|
var slideCounter = 0;
|
|
1361
1417
|
var SlideDirective = ({
|
|
@@ -1369,7 +1425,7 @@ var SlideDirective = ({
|
|
|
1369
1425
|
const [current, setCurrent] = useState3(0);
|
|
1370
1426
|
const interval = parseInt(props.interval || "3000", 10);
|
|
1371
1427
|
const speed = parseInt(props.speed || "500", 10);
|
|
1372
|
-
const elRefs =
|
|
1428
|
+
const elRefs = useRef3([]);
|
|
1373
1429
|
const [maxH, setMaxH] = useState3(0);
|
|
1374
1430
|
useLayoutEffect(() => {
|
|
1375
1431
|
let h = 0;
|
|
@@ -1382,7 +1438,7 @@ var SlideDirective = ({
|
|
|
1382
1438
|
if (elements.length <= 1) return;
|
|
1383
1439
|
setCurrent((prev) => (prev + 1) % elements.length);
|
|
1384
1440
|
}, [elements.length]);
|
|
1385
|
-
|
|
1441
|
+
useEffect3(() => {
|
|
1386
1442
|
if (elements.length <= 1) return;
|
|
1387
1443
|
const id = setInterval(cycle, interval);
|
|
1388
1444
|
return () => clearInterval(id);
|
|
@@ -1506,15 +1562,6 @@ var DirectiveRenderer_default = DirectiveRenderer;
|
|
|
1506
1562
|
|
|
1507
1563
|
// react/RawHtmlRenderer.tsx
|
|
1508
1564
|
import { useRef as useRef4, useEffect as useEffect4 } from "react";
|
|
1509
|
-
|
|
1510
|
-
// react/useTailwindCDN.ts
|
|
1511
|
-
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
1512
|
-
function scanTailwindCDN() {
|
|
1513
|
-
const tw = window.tailwind;
|
|
1514
|
-
if (tw?.scan) tw.scan();
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
// react/RawHtmlRenderer.tsx
|
|
1518
1565
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1519
1566
|
var RawHtmlRenderer = ({
|
|
1520
1567
|
content,
|
|
@@ -2228,12 +2275,15 @@ var NReditor = ({
|
|
|
2228
2275
|
onChange,
|
|
2229
2276
|
className,
|
|
2230
2277
|
debounceMs = 300,
|
|
2231
|
-
tailwindCDN = false
|
|
2278
|
+
tailwindCDN = false,
|
|
2279
|
+
onGuide,
|
|
2280
|
+
onConfig
|
|
2232
2281
|
}) => {
|
|
2233
2282
|
const editorRef = useRef6(null);
|
|
2234
2283
|
const [isAllFolded, setIsAllFolded] = useState5(false);
|
|
2235
2284
|
const [editorMode, setEditorMode] = useState5("editor");
|
|
2236
2285
|
const debouncedContent = useDebounce(value, debounceMs);
|
|
2286
|
+
useLazyTailwindCDN(tailwindCDN);
|
|
2237
2287
|
const handleToggleFold = () => {
|
|
2238
2288
|
if (!editorRef.current) return;
|
|
2239
2289
|
if (isAllFolded) {
|
|
@@ -2281,36 +2331,67 @@ var NReditor = ({
|
|
|
2281
2331
|
{ key: "split", icon: "vertical_split", label: "Split" },
|
|
2282
2332
|
{ key: "preview", icon: "visibility", label: "Preview" }
|
|
2283
2333
|
];
|
|
2284
|
-
return /* @__PURE__ */ jsxs8("div", { className: `
|
|
2285
|
-
/* @__PURE__ */ jsxs8("div", { className: "
|
|
2286
|
-
/* @__PURE__ */
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
{
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2334
|
+
return /* @__PURE__ */ jsxs8("div", { className: `nr-editor ${className || ""}`, children: [
|
|
2335
|
+
/* @__PURE__ */ jsxs8("div", { className: "nr-editor-toolbar", children: [
|
|
2336
|
+
/* @__PURE__ */ jsxs8("div", { className: "nr-editor-toolbar-left", children: [
|
|
2337
|
+
/* @__PURE__ */ jsx13(
|
|
2338
|
+
"button",
|
|
2339
|
+
{
|
|
2340
|
+
onClick: handleToggleFold,
|
|
2341
|
+
className: "nr-toolbar-btn nr-toolbar-btn-fold",
|
|
2342
|
+
title: isAllFolded ? "Expandir todo" : "Colapsar todo",
|
|
2343
|
+
"aria-label": isAllFolded ? "Expandir todo" : "Colapsar todo",
|
|
2344
|
+
children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-rounded", children: isAllFolded ? "unfold_more" : "unfold_less" })
|
|
2345
|
+
}
|
|
2346
|
+
),
|
|
2347
|
+
/* @__PURE__ */ jsx13("div", { className: "nr-toolbar-divider" }),
|
|
2348
|
+
/* @__PURE__ */ jsx13("div", { className: "nr-toolbar-mode-group", children: modeButtons.map((btn) => /* @__PURE__ */ jsxs8(
|
|
2349
|
+
"button",
|
|
2350
|
+
{
|
|
2351
|
+
onClick: () => setEditorMode(btn.key),
|
|
2352
|
+
className: `nr-toolbar-btn nr-toolbar-btn-mode ${editorMode === btn.key ? "nr-toolbar-btn-mode--active" : ""} ${btn.key === "split" ? "nr-toolbar-btn-split" : ""}`,
|
|
2353
|
+
title: btn.label,
|
|
2354
|
+
children: [
|
|
2355
|
+
/* @__PURE__ */ jsx13("span", { className: "material-symbols-rounded", children: btn.icon }),
|
|
2356
|
+
/* @__PURE__ */ jsx13("span", { className: "nr-toolbar-label", children: btn.label })
|
|
2357
|
+
]
|
|
2358
|
+
},
|
|
2359
|
+
btn.key
|
|
2360
|
+
)) })
|
|
2361
|
+
] }),
|
|
2362
|
+
/* @__PURE__ */ jsxs8("div", { className: "nr-editor-toolbar-right", children: [
|
|
2363
|
+
onGuide && /* @__PURE__ */ jsxs8(
|
|
2364
|
+
"button",
|
|
2365
|
+
{
|
|
2366
|
+
onClick: onGuide,
|
|
2367
|
+
className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-guide",
|
|
2368
|
+
title: "Gu\xEDa de sintaxis",
|
|
2369
|
+
children: [
|
|
2370
|
+
/* @__PURE__ */ jsx13("span", { className: "material-symbols-rounded", children: "menu_book" }),
|
|
2371
|
+
/* @__PURE__ */ jsx13("span", { className: "nr-toolbar-label", children: "Gu\xEDa" })
|
|
2372
|
+
]
|
|
2373
|
+
}
|
|
2374
|
+
),
|
|
2375
|
+
onGuide && onConfig && /* @__PURE__ */ jsx13("div", { className: "nr-toolbar-divider" }),
|
|
2376
|
+
onConfig && /* @__PURE__ */ jsxs8(
|
|
2377
|
+
"button",
|
|
2378
|
+
{
|
|
2379
|
+
onClick: onConfig,
|
|
2380
|
+
className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-config",
|
|
2381
|
+
title: "Configurar tema y metadata",
|
|
2382
|
+
children: [
|
|
2383
|
+
/* @__PURE__ */ jsx13("span", { className: "material-symbols-rounded", children: "tune" }),
|
|
2384
|
+
/* @__PURE__ */ jsx13("span", { className: "nr-toolbar-label", children: "Configurar" })
|
|
2385
|
+
]
|
|
2386
|
+
}
|
|
2387
|
+
)
|
|
2388
|
+
] })
|
|
2308
2389
|
] }),
|
|
2309
|
-
/* @__PURE__ */ jsxs8("div", { className: "
|
|
2390
|
+
/* @__PURE__ */ jsxs8("div", { className: "nr-editor-body", children: [
|
|
2310
2391
|
(editorMode === "editor" || editorMode === "split") && /* @__PURE__ */ jsx13(
|
|
2311
2392
|
"div",
|
|
2312
2393
|
{
|
|
2313
|
-
className:
|
|
2394
|
+
className: `nr-editor-pane ${editorMode === "split" ? "nr-editor-pane--half" : ""}`,
|
|
2314
2395
|
children: /* @__PURE__ */ jsx13(
|
|
2315
2396
|
CodeMirror,
|
|
2316
2397
|
{
|
|
@@ -2333,8 +2414,8 @@ var NReditor = ({
|
|
|
2333
2414
|
(editorMode === "preview" || editorMode === "split") && /* @__PURE__ */ jsx13(
|
|
2334
2415
|
"div",
|
|
2335
2416
|
{
|
|
2336
|
-
className:
|
|
2337
|
-
children: /* @__PURE__ */ jsx13("div", { className: "nr-prose
|
|
2417
|
+
className: `nr-editor-preview ${editorMode === "split" ? "nr-editor-preview--half" : ""}`,
|
|
2418
|
+
children: /* @__PURE__ */ jsx13("div", { className: "nr-editor-prose", children: /* @__PURE__ */ jsx13("div", { className: "nr-prose", children: /* @__PURE__ */ jsx13(CustomMarkdownRenderer_default, { content: debouncedContent }) }) })
|
|
2338
2419
|
}
|
|
2339
2420
|
)
|
|
2340
2421
|
] })
|