@noirmd/previewer 1.1.1 → 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 +139 -58
- 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 +124 -43
- package/dist/NReditor.js.map +1 -1
- package/dist/editor.css +179 -0
- package/editor.css +179 -0
- package/package.json +4 -2
package/dist/NReditor.cjs
CHANGED
|
@@ -347,6 +347,62 @@ function useDebounce(value, delay) {
|
|
|
347
347
|
return debouncedValue;
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
+
// react/useTailwindCDN.ts
|
|
351
|
+
var import_react2 = require("react");
|
|
352
|
+
var CDN_URL = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
|
|
353
|
+
var SCRIPT_ID = "tailwind-cdn-v4-runtime";
|
|
354
|
+
var CONFIG_ID = "tailwind-cdn-v4-config";
|
|
355
|
+
var TAILWIND_CDN_CONFIG = `
|
|
356
|
+
window.tailwind = window.tailwind || {};
|
|
357
|
+
window.tailwind.config = {
|
|
358
|
+
corePlugins: {
|
|
359
|
+
preflight: false,
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
`;
|
|
363
|
+
function useLazyTailwindCDN(enabled) {
|
|
364
|
+
const loadedRef = (0, import_react2.useRef)(false);
|
|
365
|
+
(0, import_react2.useEffect)(() => {
|
|
366
|
+
if (!enabled) {
|
|
367
|
+
window.__twCDNRefs = (window.__twCDNRefs ?? 1) - 1;
|
|
368
|
+
if ((window.__twCDNRefs ?? 0) <= 0) {
|
|
369
|
+
document.getElementById(SCRIPT_ID)?.remove();
|
|
370
|
+
document.getElementById(CONFIG_ID)?.remove();
|
|
371
|
+
window.__twCDNRefs = 0;
|
|
372
|
+
loadedRef.current = false;
|
|
373
|
+
}
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
window.__twCDNRefs = (window.__twCDNRefs ?? 0) + 1;
|
|
377
|
+
if (!document.getElementById(CONFIG_ID)) {
|
|
378
|
+
const configScript = document.createElement("script");
|
|
379
|
+
configScript.id = CONFIG_ID;
|
|
380
|
+
configScript.textContent = TAILWIND_CDN_CONFIG;
|
|
381
|
+
document.head.appendChild(configScript);
|
|
382
|
+
}
|
|
383
|
+
if (!document.getElementById(SCRIPT_ID)) {
|
|
384
|
+
const script = document.createElement("script");
|
|
385
|
+
script.id = SCRIPT_ID;
|
|
386
|
+
script.src = CDN_URL;
|
|
387
|
+
document.head.appendChild(script);
|
|
388
|
+
loadedRef.current = true;
|
|
389
|
+
}
|
|
390
|
+
return () => {
|
|
391
|
+
window.__twCDNRefs = (window.__twCDNRefs ?? 1) - 1;
|
|
392
|
+
if ((window.__twCDNRefs ?? 0) <= 0) {
|
|
393
|
+
document.getElementById(SCRIPT_ID)?.remove();
|
|
394
|
+
document.getElementById(CONFIG_ID)?.remove();
|
|
395
|
+
window.__twCDNRefs = 0;
|
|
396
|
+
loadedRef.current = false;
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}, [enabled]);
|
|
400
|
+
}
|
|
401
|
+
function scanTailwindCDN() {
|
|
402
|
+
const tw = window.tailwind;
|
|
403
|
+
if (tw?.scan) tw.scan();
|
|
404
|
+
}
|
|
405
|
+
|
|
350
406
|
// react/CustomMarkdownRenderer.tsx
|
|
351
407
|
var import_react10 = __toESM(require("react"), 1);
|
|
352
408
|
|
|
@@ -769,7 +825,7 @@ function splitSlots(rawContent) {
|
|
|
769
825
|
}
|
|
770
826
|
|
|
771
827
|
// react/ui-components.tsx
|
|
772
|
-
var
|
|
828
|
+
var import_react3 = require("react");
|
|
773
829
|
|
|
774
830
|
// react/highlightSetup.ts
|
|
775
831
|
var import_core = __toESM(require("highlight.js/lib/core"), 1);
|
|
@@ -861,8 +917,8 @@ var IconRenderer = ({ iconName, extraClasses = "" }) => {
|
|
|
861
917
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: baseClass, "aria-hidden": "true", children: iconName });
|
|
862
918
|
};
|
|
863
919
|
var CodeBlock = ({ code, language, title }) => {
|
|
864
|
-
const [copied, setCopied] = (0,
|
|
865
|
-
const timerRef = (0,
|
|
920
|
+
const [copied, setCopied] = (0, import_react3.useState)(false);
|
|
921
|
+
const timerRef = (0, import_react3.useRef)(null);
|
|
866
922
|
const lang = language?.split(/[\s{]/)[0]?.trim() || "";
|
|
867
923
|
let html;
|
|
868
924
|
try {
|
|
@@ -928,7 +984,7 @@ var Details = ({
|
|
|
928
984
|
style,
|
|
929
985
|
children
|
|
930
986
|
}) => {
|
|
931
|
-
const [isOpen, setIsOpen] = (0,
|
|
987
|
+
const [isOpen, setIsOpen] = (0, import_react3.useState)(defaultOpen);
|
|
932
988
|
const iconToRender = icon || "play_arrow";
|
|
933
989
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
934
990
|
"details",
|
|
@@ -1130,7 +1186,7 @@ var AdmonitionDirective = ({
|
|
|
1130
1186
|
var AdmonitionDirective_default = AdmonitionDirective;
|
|
1131
1187
|
|
|
1132
1188
|
// react/directives/CardDirective.tsx
|
|
1133
|
-
var
|
|
1189
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
1134
1190
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1135
1191
|
var CardDirective = ({
|
|
1136
1192
|
directiveType,
|
|
@@ -1140,7 +1196,7 @@ var CardDirective = ({
|
|
|
1140
1196
|
context,
|
|
1141
1197
|
options = {}
|
|
1142
1198
|
}) => {
|
|
1143
|
-
const stableId = (0,
|
|
1199
|
+
const stableId = (0, import_react4.useId)();
|
|
1144
1200
|
const { title, image, icon, class: customClass, url, target } = props;
|
|
1145
1201
|
const hasDescription = !!slots.description;
|
|
1146
1202
|
const { isSingleCard } = options;
|
|
@@ -1151,7 +1207,7 @@ var CardDirective = ({
|
|
|
1151
1207
|
const inlineStyles = props.style ? parseCssString(props.style) : {};
|
|
1152
1208
|
const description = hasDescription ? renderSlot("description") : null;
|
|
1153
1209
|
const content = renderSlot("content") || renderSlot("default");
|
|
1154
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react4.default.Fragment, { children: [
|
|
1155
1211
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1156
1212
|
"div",
|
|
1157
1213
|
{
|
|
@@ -1236,14 +1292,14 @@ var DetailsDirective = ({
|
|
|
1236
1292
|
var DetailsDirective_default = DetailsDirective;
|
|
1237
1293
|
|
|
1238
1294
|
// react/directives/ModalDirective.tsx
|
|
1239
|
-
var
|
|
1295
|
+
var import_react5 = require("react");
|
|
1240
1296
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1241
1297
|
var ModalDirective = ({
|
|
1242
1298
|
props,
|
|
1243
1299
|
renderSlot,
|
|
1244
1300
|
context
|
|
1245
1301
|
}) => {
|
|
1246
|
-
const stableId = (0,
|
|
1302
|
+
const stableId = (0, import_react5.useId)();
|
|
1247
1303
|
const modalId = `modal-${props.id || stableId}`;
|
|
1248
1304
|
const label = props.label || props.title || "Open";
|
|
1249
1305
|
const modalTitle = props.title || "Modal";
|
|
@@ -1287,7 +1343,7 @@ var ModalDirective = ({
|
|
|
1287
1343
|
var ModalDirective_default = ModalDirective;
|
|
1288
1344
|
|
|
1289
1345
|
// react/directives/ButtonDirective.tsx
|
|
1290
|
-
var
|
|
1346
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
1291
1347
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1292
1348
|
var ButtonDirective = ({
|
|
1293
1349
|
props,
|
|
@@ -1330,13 +1386,13 @@ var ButtonDirective = ({
|
|
|
1330
1386
|
const slotContent = renderSlot("default");
|
|
1331
1387
|
const findLinks = (element) => {
|
|
1332
1388
|
if (!element) return [];
|
|
1333
|
-
if (
|
|
1389
|
+
if (import_react6.default.isValidElement(element) && element.type === "a") {
|
|
1334
1390
|
return [element];
|
|
1335
1391
|
}
|
|
1336
1392
|
if (Array.isArray(element)) {
|
|
1337
1393
|
return element.flatMap(findLinks);
|
|
1338
1394
|
}
|
|
1339
|
-
if (
|
|
1395
|
+
if (import_react6.default.isValidElement(element) && element.props.children) {
|
|
1340
1396
|
return findLinks(element.props.children);
|
|
1341
1397
|
}
|
|
1342
1398
|
return [];
|
|
@@ -1344,7 +1400,7 @@ var ButtonDirective = ({
|
|
|
1344
1400
|
const links = findLinks(slotContent);
|
|
1345
1401
|
if (links.length > 0) {
|
|
1346
1402
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `not-prose ${wrapperClass}`.trim(), children: links.map(
|
|
1347
|
-
(link, index) =>
|
|
1403
|
+
(link, index) => import_react6.default.cloneElement(
|
|
1348
1404
|
link,
|
|
1349
1405
|
{
|
|
1350
1406
|
key: index,
|
|
@@ -1389,7 +1445,7 @@ var WrapperDirective = ({
|
|
|
1389
1445
|
var WrapperDirective_default = WrapperDirective;
|
|
1390
1446
|
|
|
1391
1447
|
// react/directives/SlideDirective.tsx
|
|
1392
|
-
var
|
|
1448
|
+
var import_react7 = require("react");
|
|
1393
1449
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1394
1450
|
var slideCounter = 0;
|
|
1395
1451
|
var SlideDirective = ({
|
|
@@ -1400,23 +1456,23 @@ var SlideDirective = ({
|
|
|
1400
1456
|
const rawContent = slots.default || "";
|
|
1401
1457
|
const lines = rawContent.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
1402
1458
|
const elements = lines.map((line) => context.parseMarkdown(line));
|
|
1403
|
-
const [current, setCurrent] = (0,
|
|
1459
|
+
const [current, setCurrent] = (0, import_react7.useState)(0);
|
|
1404
1460
|
const interval = parseInt(props.interval || "3000", 10);
|
|
1405
1461
|
const speed = parseInt(props.speed || "500", 10);
|
|
1406
|
-
const elRefs = (0,
|
|
1407
|
-
const [maxH, setMaxH] = (0,
|
|
1408
|
-
(0,
|
|
1462
|
+
const elRefs = (0, import_react7.useRef)([]);
|
|
1463
|
+
const [maxH, setMaxH] = (0, import_react7.useState)(0);
|
|
1464
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
1409
1465
|
let h = 0;
|
|
1410
1466
|
elRefs.current.forEach((el) => {
|
|
1411
1467
|
if (el) h = Math.max(h, el.offsetHeight);
|
|
1412
1468
|
});
|
|
1413
1469
|
if (h > 0) setMaxH(h);
|
|
1414
1470
|
}, [elements]);
|
|
1415
|
-
const cycle = (0,
|
|
1471
|
+
const cycle = (0, import_react7.useCallback)(() => {
|
|
1416
1472
|
if (elements.length <= 1) return;
|
|
1417
1473
|
setCurrent((prev) => (prev + 1) % elements.length);
|
|
1418
1474
|
}, [elements.length]);
|
|
1419
|
-
(0,
|
|
1475
|
+
(0, import_react7.useEffect)(() => {
|
|
1420
1476
|
if (elements.length <= 1) return;
|
|
1421
1477
|
const id = setInterval(cycle, interval);
|
|
1422
1478
|
return () => clearInterval(id);
|
|
@@ -1540,15 +1596,6 @@ var DirectiveRenderer_default = DirectiveRenderer;
|
|
|
1540
1596
|
|
|
1541
1597
|
// react/RawHtmlRenderer.tsx
|
|
1542
1598
|
var import_react8 = require("react");
|
|
1543
|
-
|
|
1544
|
-
// react/useTailwindCDN.ts
|
|
1545
|
-
var import_react7 = require("react");
|
|
1546
|
-
function scanTailwindCDN() {
|
|
1547
|
-
const tw = window.tailwind;
|
|
1548
|
-
if (tw?.scan) tw.scan();
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
// react/RawHtmlRenderer.tsx
|
|
1552
1599
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1553
1600
|
var RawHtmlRenderer = ({
|
|
1554
1601
|
content,
|
|
@@ -2262,12 +2309,15 @@ var NReditor = ({
|
|
|
2262
2309
|
onChange,
|
|
2263
2310
|
className,
|
|
2264
2311
|
debounceMs = 300,
|
|
2265
|
-
tailwindCDN = false
|
|
2312
|
+
tailwindCDN = false,
|
|
2313
|
+
onGuide,
|
|
2314
|
+
onConfig
|
|
2266
2315
|
}) => {
|
|
2267
2316
|
const editorRef = (0, import_react11.useRef)(null);
|
|
2268
2317
|
const [isAllFolded, setIsAllFolded] = (0, import_react11.useState)(false);
|
|
2269
2318
|
const [editorMode, setEditorMode] = (0, import_react11.useState)("editor");
|
|
2270
2319
|
const debouncedContent = useDebounce(value, debounceMs);
|
|
2320
|
+
useLazyTailwindCDN(tailwindCDN);
|
|
2271
2321
|
const handleToggleFold = () => {
|
|
2272
2322
|
if (!editorRef.current) return;
|
|
2273
2323
|
if (isAllFolded) {
|
|
@@ -2315,36 +2365,67 @@ var NReditor = ({
|
|
|
2315
2365
|
{ key: "split", icon: "vertical_split", label: "Split" },
|
|
2316
2366
|
{ key: "preview", icon: "visibility", label: "Preview" }
|
|
2317
2367
|
];
|
|
2318
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `
|
|
2319
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "
|
|
2320
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
{
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `nr-editor ${className || ""}`, children: [
|
|
2369
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-toolbar", children: [
|
|
2370
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-toolbar-left", children: [
|
|
2371
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2372
|
+
"button",
|
|
2373
|
+
{
|
|
2374
|
+
onClick: handleToggleFold,
|
|
2375
|
+
className: "nr-toolbar-btn nr-toolbar-btn-fold",
|
|
2376
|
+
title: isAllFolded ? "Expandir todo" : "Colapsar todo",
|
|
2377
|
+
"aria-label": isAllFolded ? "Expandir todo" : "Colapsar todo",
|
|
2378
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: isAllFolded ? "unfold_more" : "unfold_less" })
|
|
2379
|
+
}
|
|
2380
|
+
),
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-toolbar-divider" }),
|
|
2382
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-toolbar-mode-group", children: modeButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2383
|
+
"button",
|
|
2384
|
+
{
|
|
2385
|
+
onClick: () => setEditorMode(btn.key),
|
|
2386
|
+
className: `nr-toolbar-btn nr-toolbar-btn-mode ${editorMode === btn.key ? "nr-toolbar-btn-mode--active" : ""} ${btn.key === "split" ? "nr-toolbar-btn-split" : ""}`,
|
|
2387
|
+
title: btn.label,
|
|
2388
|
+
children: [
|
|
2389
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: btn.icon }),
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nr-toolbar-label", children: btn.label })
|
|
2391
|
+
]
|
|
2392
|
+
},
|
|
2393
|
+
btn.key
|
|
2394
|
+
)) })
|
|
2395
|
+
] }),
|
|
2396
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-toolbar-right", children: [
|
|
2397
|
+
onGuide && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2398
|
+
"button",
|
|
2399
|
+
{
|
|
2400
|
+
onClick: onGuide,
|
|
2401
|
+
className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-guide",
|
|
2402
|
+
title: "Gu\xEDa de sintaxis",
|
|
2403
|
+
children: [
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: "menu_book" }),
|
|
2405
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nr-toolbar-label", children: "Gu\xEDa" })
|
|
2406
|
+
]
|
|
2407
|
+
}
|
|
2408
|
+
),
|
|
2409
|
+
onGuide && onConfig && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-toolbar-divider" }),
|
|
2410
|
+
onConfig && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2411
|
+
"button",
|
|
2412
|
+
{
|
|
2413
|
+
onClick: onConfig,
|
|
2414
|
+
className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-config",
|
|
2415
|
+
title: "Configurar tema y metadata",
|
|
2416
|
+
children: [
|
|
2417
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: "tune" }),
|
|
2418
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nr-toolbar-label", children: "Configurar" })
|
|
2419
|
+
]
|
|
2420
|
+
}
|
|
2421
|
+
)
|
|
2422
|
+
] })
|
|
2342
2423
|
] }),
|
|
2343
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "
|
|
2424
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-body", children: [
|
|
2344
2425
|
(editorMode === "editor" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2345
2426
|
"div",
|
|
2346
2427
|
{
|
|
2347
|
-
className:
|
|
2428
|
+
className: `nr-editor-pane ${editorMode === "split" ? "nr-editor-pane--half" : ""}`,
|
|
2348
2429
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2349
2430
|
import_react_codemirror.default,
|
|
2350
2431
|
{
|
|
@@ -2367,8 +2448,8 @@ var NReditor = ({
|
|
|
2367
2448
|
(editorMode === "preview" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2368
2449
|
"div",
|
|
2369
2450
|
{
|
|
2370
|
-
className:
|
|
2371
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-prose
|
|
2451
|
+
className: `nr-editor-preview ${editorMode === "split" ? "nr-editor-preview--half" : ""}`,
|
|
2452
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-editor-prose", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-prose", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CustomMarkdownRenderer_default, { content: debouncedContent }) }) })
|
|
2372
2453
|
}
|
|
2373
2454
|
)
|
|
2374
2455
|
] })
|