@noirmd/previewer 2.1.3 → 2.1.5
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 +211 -171
- package/dist/NReditor.cjs.map +1 -1
- package/dist/NReditor.js +212 -172
- package/dist/NReditor.js.map +1 -1
- package/dist/button.css +6 -0
- package/dist/card.css +10 -10
- package/dist/core.cjs +31 -20
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +1 -0
- package/dist/core.d.ts +1 -0
- package/dist/core.js +31 -20
- package/dist/core.js.map +1 -1
- package/dist/editor.css +58 -3
- package/dist/hover3d.css +1 -1
- package/dist/index.cjs +151 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +151 -159
- package/dist/index.js.map +1 -1
- package/dist/modal.css +7 -1
- package/dist/react.cjs +211 -171
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +212 -172
- package/dist/react.js.map +1 -1
- package/dist/vanilla.cjs +151 -159
- package/dist/vanilla.cjs.map +1 -1
- package/dist/vanilla.d.cts +1 -0
- package/dist/vanilla.d.ts +1 -0
- package/dist/vanilla.js +151 -159
- package/dist/vanilla.js.map +1 -1
- package/dist/vue.cjs +151 -159
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.d.cts +1 -0
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +151 -159
- package/dist/vue.js.map +1 -1
- package/editor.css +58 -3
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -1675,6 +1675,22 @@ function parseHtmlAttrs(attrsString) {
|
|
|
1675
1675
|
}
|
|
1676
1676
|
|
|
1677
1677
|
// core/parser.ts
|
|
1678
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
1679
|
+
"area",
|
|
1680
|
+
"base",
|
|
1681
|
+
"br",
|
|
1682
|
+
"col",
|
|
1683
|
+
"embed",
|
|
1684
|
+
"hr",
|
|
1685
|
+
"img",
|
|
1686
|
+
"input",
|
|
1687
|
+
"link",
|
|
1688
|
+
"meta",
|
|
1689
|
+
"param",
|
|
1690
|
+
"source",
|
|
1691
|
+
"track",
|
|
1692
|
+
"wbr"
|
|
1693
|
+
]);
|
|
1678
1694
|
function parseMarkdown(markdown2) {
|
|
1679
1695
|
if (!markdown2) return [];
|
|
1680
1696
|
const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
|
|
@@ -1688,8 +1704,19 @@ function parseMarkdown(markdown2) {
|
|
|
1688
1704
|
if (match = trimmed.match(/^(#{1,6})\s+(.+)$/)) {
|
|
1689
1705
|
const level = match[1].length;
|
|
1690
1706
|
const rawText = match[2];
|
|
1691
|
-
const { text:
|
|
1692
|
-
|
|
1707
|
+
const { text: rawParsedText, classes: classes2, id: customId } = extractAttributes(rawText);
|
|
1708
|
+
let text2 = rawParsedText;
|
|
1709
|
+
let align;
|
|
1710
|
+
const alignCenter = text2.match(/^->\s*(.+?)\s*<-\s*$/);
|
|
1711
|
+
const alignRight = text2.match(/^->\s*(.+?)\s*->\s*$/);
|
|
1712
|
+
if (alignCenter) {
|
|
1713
|
+
text2 = alignCenter[1];
|
|
1714
|
+
align = "center";
|
|
1715
|
+
} else if (alignRight) {
|
|
1716
|
+
text2 = alignRight[1];
|
|
1717
|
+
align = "right";
|
|
1718
|
+
}
|
|
1719
|
+
const baseId = customId || generateId(text2);
|
|
1693
1720
|
let id2 = baseId;
|
|
1694
1721
|
let n = 1;
|
|
1695
1722
|
while (usedIds.has(id2)) {
|
|
@@ -1697,7 +1724,7 @@ function parseMarkdown(markdown2) {
|
|
|
1697
1724
|
id2 = `${baseId}-${n}`;
|
|
1698
1725
|
}
|
|
1699
1726
|
usedIds.add(id2);
|
|
1700
|
-
result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0 });
|
|
1727
|
+
result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0, align });
|
|
1701
1728
|
i++;
|
|
1702
1729
|
continue;
|
|
1703
1730
|
}
|
|
@@ -1873,29 +1900,13 @@ function parseMarkdown(markdown2) {
|
|
|
1873
1900
|
let tagStartMatch = trimmed.match(/^<([a-zA-Z][\w-]*)/);
|
|
1874
1901
|
if (tagStartMatch) {
|
|
1875
1902
|
const tagName = tagStartMatch[1].toLowerCase();
|
|
1876
|
-
const voidElements = /* @__PURE__ */ new Set([
|
|
1877
|
-
"area",
|
|
1878
|
-
"base",
|
|
1879
|
-
"br",
|
|
1880
|
-
"col",
|
|
1881
|
-
"embed",
|
|
1882
|
-
"hr",
|
|
1883
|
-
"img",
|
|
1884
|
-
"input",
|
|
1885
|
-
"link",
|
|
1886
|
-
"meta",
|
|
1887
|
-
"param",
|
|
1888
|
-
"source",
|
|
1889
|
-
"track",
|
|
1890
|
-
"wbr"
|
|
1891
|
-
]);
|
|
1892
1903
|
const remainingText = lines.slice(i).join("\n");
|
|
1893
1904
|
const openTagRegex = new RegExp(`^\\s*<${tagName}\\b([^>]*?)>`, "i");
|
|
1894
1905
|
const openTagMatch = remainingText.match(openTagRegex);
|
|
1895
1906
|
if (openTagMatch) {
|
|
1896
1907
|
const fullOpenTag = openTagMatch[0];
|
|
1897
1908
|
const attrs = openTagMatch[1].replace(/\s+/g, " ").trim();
|
|
1898
|
-
const isSelfClosing = fullOpenTag.endsWith("/>") ||
|
|
1909
|
+
const isSelfClosing = fullOpenTag.endsWith("/>") || VOID_ELEMENTS.has(tagName);
|
|
1899
1910
|
if (isSelfClosing) {
|
|
1900
1911
|
const blockText = remainingText.substring(0, openTagMatch.index + fullOpenTag.length);
|
|
1901
1912
|
const consumedLines = blockText.split("\n").length;
|
|
@@ -11289,11 +11300,77 @@ function parseInlinePart(part) {
|
|
|
11289
11300
|
return document.createTextNode(part);
|
|
11290
11301
|
}
|
|
11291
11302
|
|
|
11303
|
+
// vanilla/utils.ts
|
|
11304
|
+
var THEME_TOKENS = /* @__PURE__ */ new Set([
|
|
11305
|
+
"primary",
|
|
11306
|
+
"secondary",
|
|
11307
|
+
"accent",
|
|
11308
|
+
"neutral",
|
|
11309
|
+
"info",
|
|
11310
|
+
"success",
|
|
11311
|
+
"warning",
|
|
11312
|
+
"error"
|
|
11313
|
+
]);
|
|
11314
|
+
function isThemeToken(color) {
|
|
11315
|
+
return !!color && THEME_TOKENS.has(color);
|
|
11316
|
+
}
|
|
11317
|
+
function isArbitraryColor(value) {
|
|
11318
|
+
if (THEME_TOKENS.has(value)) return false;
|
|
11319
|
+
if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
|
|
11320
|
+
if (/^[a-zA-Z]+$/.test(value)) return true;
|
|
11321
|
+
return false;
|
|
11322
|
+
}
|
|
11323
|
+
function applyBaseProps(el, props) {
|
|
11324
|
+
if (props.class) {
|
|
11325
|
+
el.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
11326
|
+
}
|
|
11327
|
+
if (props.style) {
|
|
11328
|
+
const styles = parseCssString(props.style);
|
|
11329
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
11330
|
+
el.style.setProperty(key, String(value));
|
|
11331
|
+
}
|
|
11332
|
+
}
|
|
11333
|
+
}
|
|
11334
|
+
function applyFloatStyle(el, float, width) {
|
|
11335
|
+
if (!float) return;
|
|
11336
|
+
if (float === "left" || float === "right") {
|
|
11337
|
+
el.style.float = float;
|
|
11338
|
+
if (!width) el.style.maxWidth = "50%";
|
|
11339
|
+
el.style.marginInlineStart = float === "right" ? "1rem" : "";
|
|
11340
|
+
el.style.marginInlineEnd = float === "left" ? "1rem" : "";
|
|
11341
|
+
} else if (float === "center") {
|
|
11342
|
+
el.style.marginInline = "auto";
|
|
11343
|
+
}
|
|
11344
|
+
}
|
|
11345
|
+
function applyColor(el, color, classSuffix) {
|
|
11346
|
+
if (!color) return "";
|
|
11347
|
+
if (isThemeToken(color)) {
|
|
11348
|
+
return ` ${classSuffix}--${color}`;
|
|
11349
|
+
}
|
|
11350
|
+
if (isArbitraryColor(color)) {
|
|
11351
|
+
el.style.background = color;
|
|
11352
|
+
el.style.color = "white";
|
|
11353
|
+
}
|
|
11354
|
+
return "";
|
|
11355
|
+
}
|
|
11356
|
+
function openModal(dialog) {
|
|
11357
|
+
if (!dialog.open) {
|
|
11358
|
+
document.body.appendChild(dialog);
|
|
11359
|
+
dialog.showModal();
|
|
11360
|
+
dialog.addEventListener("close", () => dialog.remove(), { once: true });
|
|
11361
|
+
}
|
|
11362
|
+
}
|
|
11363
|
+
var IMG_RE = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11364
|
+
function parseIntProp(value, defaultValue) {
|
|
11365
|
+
if (!value) return defaultValue;
|
|
11366
|
+
const n = parseInt(value, 10);
|
|
11367
|
+
return Number.isNaN(n) ? defaultValue : n;
|
|
11368
|
+
}
|
|
11369
|
+
|
|
11292
11370
|
// vanilla/directives/admonition.ts
|
|
11293
11371
|
var admonitionDirective = ({ directiveType, props, renderSlot }) => {
|
|
11294
11372
|
const el = createAdmonition(directiveType, props.title, props.icon);
|
|
11295
|
-
|
|
11296
|
-
if (props.style) el.setAttribute("style", props.style);
|
|
11373
|
+
applyBaseProps(el, props);
|
|
11297
11374
|
const body = el.querySelector(".nr-admonition__body");
|
|
11298
11375
|
if (body) {
|
|
11299
11376
|
body.appendChild(renderSlot("default"));
|
|
@@ -11309,8 +11386,7 @@ var detailsDirective = ({ props, renderSlot }) => {
|
|
|
11309
11386
|
props.icon,
|
|
11310
11387
|
props.defaultOpen === "true"
|
|
11311
11388
|
);
|
|
11312
|
-
|
|
11313
|
-
if (props.style) el.setAttribute("style", props.style);
|
|
11389
|
+
applyBaseProps(el, props);
|
|
11314
11390
|
const body = el.querySelector(".nr-details__body");
|
|
11315
11391
|
if (body) {
|
|
11316
11392
|
body.appendChild(renderSlot("default"));
|
|
@@ -11323,12 +11399,12 @@ var details_default = detailsDirective;
|
|
|
11323
11399
|
var modalDirective = ({ props, renderSlot }) => {
|
|
11324
11400
|
const label = props.label || props.title || "Open";
|
|
11325
11401
|
const modalTitle = props.title || "Modal";
|
|
11326
|
-
const
|
|
11402
|
+
const align = props.align || "left";
|
|
11327
11403
|
const wrapper = document.createElement("div");
|
|
11328
|
-
wrapper.className = "nr-modal-trigger"
|
|
11404
|
+
wrapper.className = `nr-modal-trigger${align === "center" ? " nr-modal-trigger--center" : align === "right" ? " nr-modal-trigger--right" : ""}`;
|
|
11329
11405
|
const btn = document.createElement("button");
|
|
11330
11406
|
btn.className = `nr-button nr-button--default`;
|
|
11331
|
-
|
|
11407
|
+
applyBaseProps(btn, props);
|
|
11332
11408
|
const icon = props.icon || "open_in_new";
|
|
11333
11409
|
if (icon) btn.appendChild(createIcon(icon));
|
|
11334
11410
|
btn.appendChild(document.createTextNode(label));
|
|
@@ -11340,15 +11416,7 @@ var modalDirective = ({ props, renderSlot }) => {
|
|
|
11340
11416
|
prose.appendChild(renderSlot("default"));
|
|
11341
11417
|
body.appendChild(prose);
|
|
11342
11418
|
}
|
|
11343
|
-
btn.addEventListener("click", () =>
|
|
11344
|
-
if (!dialog.open) {
|
|
11345
|
-
document.body.appendChild(dialog);
|
|
11346
|
-
dialog.showModal();
|
|
11347
|
-
dialog.addEventListener("close", () => {
|
|
11348
|
-
dialog.remove();
|
|
11349
|
-
}, { once: true });
|
|
11350
|
-
}
|
|
11351
|
-
});
|
|
11419
|
+
btn.addEventListener("click", () => openModal(dialog));
|
|
11352
11420
|
wrapper.appendChild(btn);
|
|
11353
11421
|
wrapper.appendChild(dialog);
|
|
11354
11422
|
return wrapper;
|
|
@@ -11358,19 +11426,20 @@ var modal_default = modalDirective;
|
|
|
11358
11426
|
// vanilla/directives/button.ts
|
|
11359
11427
|
var buttonDirective = ({ props, renderSlot }) => {
|
|
11360
11428
|
const url = props.url || props.href || "#";
|
|
11361
|
-
const label = props.label;
|
|
11429
|
+
const label = props.label || props.title;
|
|
11362
11430
|
const icon = props.icon || "near_me";
|
|
11363
11431
|
const target = props.target || "_blank";
|
|
11364
11432
|
const customClass = props.class || "";
|
|
11433
|
+
const align = props.align || "left";
|
|
11365
11434
|
const wrapper = document.createElement("div");
|
|
11366
|
-
wrapper.className = "nr-button-wrap"
|
|
11435
|
+
wrapper.className = `nr-button-wrap${align === "center" ? " nr-button-wrap--center" : align === "right" ? " nr-button-wrap--right" : ""}`;
|
|
11367
11436
|
if (label) {
|
|
11368
11437
|
const a = document.createElement("a");
|
|
11369
11438
|
a.href = url;
|
|
11370
11439
|
a.target = target;
|
|
11371
11440
|
a.rel = "noopener noreferrer";
|
|
11372
11441
|
a.className = "nr-button nr-button--default";
|
|
11373
|
-
|
|
11442
|
+
applyBaseProps(a, props);
|
|
11374
11443
|
a.appendChild(createIcon(icon));
|
|
11375
11444
|
a.appendChild(document.createTextNode(label));
|
|
11376
11445
|
wrapper.appendChild(a);
|
|
@@ -11381,7 +11450,7 @@ var buttonDirective = ({ props, renderSlot }) => {
|
|
|
11381
11450
|
if (links.length > 0) {
|
|
11382
11451
|
links.forEach((link) => {
|
|
11383
11452
|
link.classList.add("nr-button", "nr-button--default");
|
|
11384
|
-
|
|
11453
|
+
applyBaseProps(link, props);
|
|
11385
11454
|
});
|
|
11386
11455
|
wrapper.appendChild(slotContent);
|
|
11387
11456
|
} else {
|
|
@@ -11390,7 +11459,7 @@ var buttonDirective = ({ props, renderSlot }) => {
|
|
|
11390
11459
|
a.target = target;
|
|
11391
11460
|
a.rel = "noopener noreferrer";
|
|
11392
11461
|
a.className = "nr-button nr-button--default";
|
|
11393
|
-
|
|
11462
|
+
applyBaseProps(a, props);
|
|
11394
11463
|
a.appendChild(createIcon(icon));
|
|
11395
11464
|
a.appendChild(slotContent);
|
|
11396
11465
|
wrapper.appendChild(a);
|
|
@@ -11413,12 +11482,9 @@ var cardDirective = ({
|
|
|
11413
11482
|
const { isSingleCard } = options || {};
|
|
11414
11483
|
const isModal = directiveType === "card-m";
|
|
11415
11484
|
const isLink = directiveType === "card-b";
|
|
11416
|
-
const inlineStyles = props.style ? parseCssString(props.style) : {};
|
|
11417
11485
|
const card = document.createElement("div");
|
|
11418
11486
|
card.className = `nr-card${isModal || isLink ? " nr-card--interactive" : ""} ${customClass}`.trim();
|
|
11419
|
-
|
|
11420
|
-
card.style.setProperty(key, String(value));
|
|
11421
|
-
}
|
|
11487
|
+
applyBaseProps(card, props);
|
|
11422
11488
|
if (image) {
|
|
11423
11489
|
const imgWrap = document.createElement("div");
|
|
11424
11490
|
imgWrap.className = `nr-card__image${isSingleCard ? " nr-card__image--tall" : ""}`;
|
|
@@ -11497,13 +11563,7 @@ var cardDirective = ({
|
|
|
11497
11563
|
prose.appendChild(renderSlot("content") || renderSlot("default"));
|
|
11498
11564
|
modalBody.appendChild(prose);
|
|
11499
11565
|
}
|
|
11500
|
-
card.addEventListener("click", () =>
|
|
11501
|
-
if (!dialog.open) {
|
|
11502
|
-
document.body.appendChild(dialog);
|
|
11503
|
-
dialog.showModal();
|
|
11504
|
-
dialog.addEventListener("close", () => dialog.remove(), { once: true });
|
|
11505
|
-
}
|
|
11506
|
-
});
|
|
11566
|
+
card.addEventListener("click", () => openModal(dialog));
|
|
11507
11567
|
const frag = document.createDocumentFragment();
|
|
11508
11568
|
frag.appendChild(card);
|
|
11509
11569
|
frag.appendChild(dialog);
|
|
@@ -11551,8 +11611,8 @@ var slideDirective = ({
|
|
|
11551
11611
|
if (lines.length === 0) {
|
|
11552
11612
|
return document.createDocumentFragment();
|
|
11553
11613
|
}
|
|
11554
|
-
const interval =
|
|
11555
|
-
const speed =
|
|
11614
|
+
const interval = parseIntProp(props.interval, 3e3);
|
|
11615
|
+
const speed = parseIntProp(props.speed, 500);
|
|
11556
11616
|
const rawClass = props.class || "";
|
|
11557
11617
|
const inlineStyle = props.style ? parseCssString(props.style) : {};
|
|
11558
11618
|
const scopeClass = `sld-${++slideCounter}`;
|
|
@@ -11603,10 +11663,11 @@ var slideDirective = ({
|
|
|
11603
11663
|
}
|
|
11604
11664
|
});
|
|
11605
11665
|
if (lines.length > 1) {
|
|
11606
|
-
setInterval(() => {
|
|
11666
|
+
const id = setInterval(() => {
|
|
11607
11667
|
current = (current + 1) % lines.length;
|
|
11608
11668
|
track.style.transform = `translateY(${-current * maxH}px)`;
|
|
11609
11669
|
}, interval);
|
|
11670
|
+
container.dataset.nrIntervalId = String(id);
|
|
11610
11671
|
}
|
|
11611
11672
|
return container;
|
|
11612
11673
|
};
|
|
@@ -11616,8 +11677,7 @@ var slide_default = slideDirective;
|
|
|
11616
11677
|
var keysDirective = ({ props, slots }) => {
|
|
11617
11678
|
const wrap = document.createElement("div");
|
|
11618
11679
|
wrap.className = "nr-keys";
|
|
11619
|
-
|
|
11620
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11680
|
+
applyBaseProps(wrap, props);
|
|
11621
11681
|
const sizeClass = props.size ? ` nr-kbd--${props.size}` : "";
|
|
11622
11682
|
const parts = (slots.default || "").split("+").map((p) => p.trim()).filter(Boolean);
|
|
11623
11683
|
parts.forEach((part, i) => {
|
|
@@ -11641,8 +11701,7 @@ var accordionCounter = 0;
|
|
|
11641
11701
|
var accordionItemDirective = ({ props, renderSlot }) => {
|
|
11642
11702
|
const item = document.createElement("div");
|
|
11643
11703
|
item.className = "nr-accordion__item";
|
|
11644
|
-
|
|
11645
|
-
if (props.style) item.setAttribute("style", props.style);
|
|
11704
|
+
applyBaseProps(item, props);
|
|
11646
11705
|
const input = document.createElement("input");
|
|
11647
11706
|
input.type = "radio";
|
|
11648
11707
|
input.className = "nr-accordion__input";
|
|
@@ -11661,8 +11720,7 @@ var accordionItemDirective = ({ props, renderSlot }) => {
|
|
|
11661
11720
|
var accordionDirective = ({ props, renderSlot }) => {
|
|
11662
11721
|
const wrap = document.createElement("div");
|
|
11663
11722
|
wrap.className = "nr-accordion";
|
|
11664
|
-
|
|
11665
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11723
|
+
applyBaseProps(wrap, props);
|
|
11666
11724
|
wrap.appendChild(renderSlot("default"));
|
|
11667
11725
|
const mode = props.mode === "checkbox" ? "checkbox" : "radio";
|
|
11668
11726
|
const group = `nr-acc-${++accordionCounter}`;
|
|
@@ -11675,7 +11733,6 @@ var accordionDirective = ({ props, renderSlot }) => {
|
|
|
11675
11733
|
var accordion_default = accordionDirective;
|
|
11676
11734
|
|
|
11677
11735
|
// vanilla/directives/carousel.ts
|
|
11678
|
-
var IMG_RE = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11679
11736
|
var carouselDirective = ({ props, slots }) => {
|
|
11680
11737
|
const images = [];
|
|
11681
11738
|
const raw = slots.default || "";
|
|
@@ -11691,19 +11748,9 @@ var carouselDirective = ({ props, slots }) => {
|
|
|
11691
11748
|
wrap.className = "nr-carousel";
|
|
11692
11749
|
wrap.tabIndex = 0;
|
|
11693
11750
|
wrap.setAttribute("aria-label", "Image carousel");
|
|
11694
|
-
|
|
11695
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11751
|
+
applyBaseProps(wrap, props);
|
|
11696
11752
|
if (props.width) wrap.style.width = props.width;
|
|
11697
|
-
|
|
11698
|
-
if (props.float === "left" || props.float === "right") {
|
|
11699
|
-
wrap.style.float = props.float;
|
|
11700
|
-
if (!props.width) wrap.style.maxWidth = "50%";
|
|
11701
|
-
wrap.style.marginInlineStart = props.float === "right" ? "1rem" : "";
|
|
11702
|
-
wrap.style.marginInlineEnd = props.float === "left" ? "1rem" : "";
|
|
11703
|
-
} else if (props.float === "center") {
|
|
11704
|
-
wrap.style.marginInline = "auto";
|
|
11705
|
-
}
|
|
11706
|
-
}
|
|
11753
|
+
applyFloatStyle(wrap, props.float, props.width);
|
|
11707
11754
|
const viewport = document.createElement("div");
|
|
11708
11755
|
viewport.className = "nr-carousel__viewport";
|
|
11709
11756
|
if (props.height) viewport.style.height = props.height;
|
|
@@ -11773,11 +11820,10 @@ var DEFAULT_LABELS = ["days", "hours", "min", "sec"];
|
|
|
11773
11820
|
var countdownDirective = ({ props }) => {
|
|
11774
11821
|
const wrap = document.createElement("div");
|
|
11775
11822
|
wrap.className = "nr-countdown";
|
|
11776
|
-
|
|
11777
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11823
|
+
applyBaseProps(wrap, props);
|
|
11778
11824
|
const labelParts = (props.labels || "").split("|").map((s) => s.trim());
|
|
11779
11825
|
const labels = DEFAULT_LABELS.map((label, i) => labelParts[i] || label);
|
|
11780
|
-
const digits =
|
|
11826
|
+
const digits = parseIntProp(props.digits, 2);
|
|
11781
11827
|
const targetTime = props.target ? new Date(props.target).getTime() : NaN;
|
|
11782
11828
|
const hasTarget = !Number.isNaN(targetTime);
|
|
11783
11829
|
const blocks = [];
|
|
@@ -11824,13 +11870,15 @@ var countdownDirective = ({ props }) => {
|
|
|
11824
11870
|
blocks.push({ value });
|
|
11825
11871
|
});
|
|
11826
11872
|
render();
|
|
11827
|
-
if (hasTarget)
|
|
11873
|
+
if (hasTarget) {
|
|
11874
|
+
const id = setInterval(render, 1e3);
|
|
11875
|
+
wrap.dataset.nrIntervalId = String(id);
|
|
11876
|
+
}
|
|
11828
11877
|
return wrap;
|
|
11829
11878
|
};
|
|
11830
11879
|
var countdown_default = countdownDirective;
|
|
11831
11880
|
|
|
11832
11881
|
// vanilla/directives/diff.ts
|
|
11833
|
-
var IMG_RE2 = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11834
11882
|
var diffDirective = ({ props, slots }) => {
|
|
11835
11883
|
let before = (props.before || "").split("#")[0].trim();
|
|
11836
11884
|
let after = (props.after || "").split("#")[0].trim();
|
|
@@ -11838,8 +11886,8 @@ var diffDirective = ({ props, slots }) => {
|
|
|
11838
11886
|
const urls = [];
|
|
11839
11887
|
const raw = slots.default || "";
|
|
11840
11888
|
let m;
|
|
11841
|
-
|
|
11842
|
-
while ((m =
|
|
11889
|
+
IMG_RE.lastIndex = 0;
|
|
11890
|
+
while ((m = IMG_RE.exec(raw)) !== null) {
|
|
11843
11891
|
urls.push(m[2].split("#")[0].trim());
|
|
11844
11892
|
}
|
|
11845
11893
|
if (!before && urls.length > 0) before = urls[0];
|
|
@@ -11852,21 +11900,11 @@ var diffDirective = ({ props, slots }) => {
|
|
|
11852
11900
|
figure.className = "nr-diff";
|
|
11853
11901
|
figure.tabIndex = 0;
|
|
11854
11902
|
figure.setAttribute("aria-label", "Image comparison slider");
|
|
11855
|
-
|
|
11856
|
-
if (props.style) figure.setAttribute("style", props.style);
|
|
11903
|
+
applyBaseProps(figure, props);
|
|
11857
11904
|
if (props.aspect) figure.style.aspectRatio = props.aspect;
|
|
11858
11905
|
if (props.height) figure.style.height = props.height;
|
|
11859
11906
|
if (props.width) figure.style.width = props.width;
|
|
11860
|
-
|
|
11861
|
-
if (props.float === "left" || props.float === "right") {
|
|
11862
|
-
figure.style.float = props.float;
|
|
11863
|
-
if (!props.width) figure.style.maxWidth = "50%";
|
|
11864
|
-
figure.style.marginInlineStart = props.float === "right" ? "1rem" : "";
|
|
11865
|
-
figure.style.marginInlineEnd = props.float === "left" ? "1rem" : "";
|
|
11866
|
-
} else if (props.float === "center") {
|
|
11867
|
-
figure.style.marginInline = "auto";
|
|
11868
|
-
}
|
|
11869
|
-
}
|
|
11907
|
+
applyFloatStyle(figure, props.float, props.width);
|
|
11870
11908
|
const beforeItem = document.createElement("div");
|
|
11871
11909
|
beforeItem.className = "nr-diff__item nr-diff__item--before";
|
|
11872
11910
|
beforeItem.setAttribute("role", "img");
|
|
@@ -11929,8 +11967,7 @@ var diff_default = diffDirective;
|
|
|
11929
11967
|
var hover3dDirective = ({ props, renderSlot }) => {
|
|
11930
11968
|
const container = document.createElement("div");
|
|
11931
11969
|
container.className = "nr-hover-3d";
|
|
11932
|
-
|
|
11933
|
-
if (props.style) container.setAttribute("style", props.style);
|
|
11970
|
+
applyBaseProps(container, props);
|
|
11934
11971
|
const stage = document.createElement("div");
|
|
11935
11972
|
stage.className = "nr-hover-3d__stage";
|
|
11936
11973
|
stage.appendChild(renderSlot("default"));
|
|
@@ -11943,14 +11980,13 @@ var hover3dDirective = ({ props, renderSlot }) => {
|
|
|
11943
11980
|
var hover3d_default = hover3dDirective;
|
|
11944
11981
|
|
|
11945
11982
|
// vanilla/directives/hovergallery.ts
|
|
11946
|
-
var IMG_RE3 = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11947
11983
|
var MAX_IMAGES = 10;
|
|
11948
11984
|
var hovergalleryDirective = ({ props, slots }) => {
|
|
11949
11985
|
const images = [];
|
|
11950
11986
|
const raw = slots.default || "";
|
|
11951
11987
|
let m;
|
|
11952
|
-
|
|
11953
|
-
while ((m =
|
|
11988
|
+
IMG_RE.lastIndex = 0;
|
|
11989
|
+
while ((m = IMG_RE.exec(raw)) !== null) {
|
|
11954
11990
|
images.push({ src: m[2].split("#")[0].trim(), alt: m[1].trim() || "gallery image" });
|
|
11955
11991
|
}
|
|
11956
11992
|
if (images.length === 0) {
|
|
@@ -11959,9 +11995,8 @@ var hovergalleryDirective = ({ props, slots }) => {
|
|
|
11959
11995
|
const count = Math.min(images.length, MAX_IMAGES);
|
|
11960
11996
|
const figure = document.createElement("figure");
|
|
11961
11997
|
figure.className = "nr-hover-gallery";
|
|
11998
|
+
applyBaseProps(figure, props);
|
|
11962
11999
|
if (props.aspect) figure.style.aspectRatio = props.aspect;
|
|
11963
|
-
if (props.class) figure.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
11964
|
-
if (props.style) figure.setAttribute("style", (figure.getAttribute("style") || "") + ";" + props.style);
|
|
11965
12000
|
const imgEls = [];
|
|
11966
12001
|
for (let i = 0; i < count; i++) {
|
|
11967
12002
|
const el = document.createElement("img");
|
|
@@ -12011,28 +12046,11 @@ var hovergalleryDirective = ({ props, slots }) => {
|
|
|
12011
12046
|
var hovergallery_default = hovergalleryDirective;
|
|
12012
12047
|
|
|
12013
12048
|
// vanilla/directives/chat.ts
|
|
12014
|
-
var CHAT_THEME_TOKENS = /* @__PURE__ */ new Set([
|
|
12015
|
-
"primary",
|
|
12016
|
-
"secondary",
|
|
12017
|
-
"accent",
|
|
12018
|
-
"neutral",
|
|
12019
|
-
"info",
|
|
12020
|
-
"success",
|
|
12021
|
-
"warning",
|
|
12022
|
-
"error"
|
|
12023
|
-
]);
|
|
12024
|
-
function isArbitraryColor(value) {
|
|
12025
|
-
if (CHAT_THEME_TOKENS.has(value)) return false;
|
|
12026
|
-
if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
|
|
12027
|
-
if (/^[a-zA-Z]+$/.test(value)) return true;
|
|
12028
|
-
return false;
|
|
12029
|
-
}
|
|
12030
12049
|
var chatItemDirective = ({ props, renderSlot }) => {
|
|
12031
12050
|
const side = props.side === "end" ? "end" : "start";
|
|
12032
12051
|
const wrap = document.createElement("div");
|
|
12033
12052
|
wrap.className = `nr-chat nr-chat--${side}`;
|
|
12034
|
-
|
|
12035
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
12053
|
+
applyBaseProps(wrap, props);
|
|
12036
12054
|
const header = document.createElement("div");
|
|
12037
12055
|
header.className = "nr-chat__header";
|
|
12038
12056
|
if (props.name) {
|
|
@@ -12057,14 +12075,8 @@ var chatItemDirective = ({ props, renderSlot }) => {
|
|
|
12057
12075
|
avatar.appendChild(img);
|
|
12058
12076
|
wrap.appendChild(avatar);
|
|
12059
12077
|
}
|
|
12060
|
-
const isThemeToken = CHAT_THEME_TOKENS.has(props.color || "");
|
|
12061
|
-
const colorClass = isThemeToken ? ` nr-chat__bubble--${props.color}` : "";
|
|
12062
12078
|
const bubble = document.createElement("div");
|
|
12063
|
-
bubble.className = `nr-chat__bubble${
|
|
12064
|
-
if (props.color && isArbitraryColor(props.color) && !isThemeToken) {
|
|
12065
|
-
bubble.style.background = props.color;
|
|
12066
|
-
bubble.style.color = "white";
|
|
12067
|
-
}
|
|
12079
|
+
bubble.className = `nr-chat__bubble${applyColor(bubble, props.color, "nr-chat__bubble")}`;
|
|
12068
12080
|
bubble.appendChild(renderSlot("default"));
|
|
12069
12081
|
wrap.appendChild(bubble);
|
|
12070
12082
|
if (props.footer) {
|
|
@@ -12078,8 +12090,7 @@ var chatItemDirective = ({ props, renderSlot }) => {
|
|
|
12078
12090
|
var chatDirective = ({ props, renderSlot }) => {
|
|
12079
12091
|
const wrap = document.createElement("div");
|
|
12080
12092
|
wrap.className = "nr-chat";
|
|
12081
|
-
|
|
12082
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
12093
|
+
applyBaseProps(wrap, props);
|
|
12083
12094
|
wrap.appendChild(renderSlot("default"));
|
|
12084
12095
|
return wrap;
|
|
12085
12096
|
};
|
|
@@ -12115,8 +12126,7 @@ function bindEventProp(el, eventProp) {
|
|
|
12115
12126
|
var richlistItemDirective = ({ props, renderSlot }) => {
|
|
12116
12127
|
const li = document.createElement("li");
|
|
12117
12128
|
li.className = "nr-richlist__item";
|
|
12118
|
-
|
|
12119
|
-
if (props.style) li.setAttribute("style", props.style);
|
|
12129
|
+
applyBaseProps(li, props);
|
|
12120
12130
|
if (props.image) {
|
|
12121
12131
|
const thumb = document.createElement("div");
|
|
12122
12132
|
thumb.className = "nr-richlist__thumb";
|
|
@@ -12178,36 +12188,20 @@ var richlistItemDirective = ({ props, renderSlot }) => {
|
|
|
12178
12188
|
var richlistDirective = ({ props, renderSlot }) => {
|
|
12179
12189
|
const ul = document.createElement("ul");
|
|
12180
12190
|
ul.className = "nr-richlist";
|
|
12181
|
-
|
|
12182
|
-
if (props.style) ul.setAttribute("style", props.style);
|
|
12191
|
+
applyBaseProps(ul, props);
|
|
12183
12192
|
ul.appendChild(renderSlot("default"));
|
|
12184
12193
|
return ul;
|
|
12185
12194
|
};
|
|
12186
12195
|
var richlist_default = richlistDirective;
|
|
12187
12196
|
|
|
12188
12197
|
// vanilla/directives/stat.ts
|
|
12189
|
-
var STAT_THEME_TOKENS = /* @__PURE__ */ new Set([
|
|
12190
|
-
"primary",
|
|
12191
|
-
"secondary",
|
|
12192
|
-
"info",
|
|
12193
|
-
"success",
|
|
12194
|
-
"warning",
|
|
12195
|
-
"error"
|
|
12196
|
-
]);
|
|
12197
|
-
function isArbitraryColor2(value) {
|
|
12198
|
-
if (STAT_THEME_TOKENS.has(value)) return false;
|
|
12199
|
-
if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
|
|
12200
|
-
if (/^[a-zA-Z]+$/.test(value)) return true;
|
|
12201
|
-
return false;
|
|
12202
|
-
}
|
|
12203
12198
|
var statDirective = ({ props }) => {
|
|
12204
|
-
const
|
|
12205
|
-
const colorClass =
|
|
12199
|
+
const statIsThemeToken = isThemeToken(props.color);
|
|
12200
|
+
const colorClass = statIsThemeToken ? ` nr-stat--${props.color}` : "";
|
|
12206
12201
|
const stat = document.createElement("div");
|
|
12207
12202
|
stat.className = `nr-stat${colorClass}`;
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
const useInlineColor = props.color && isArbitraryColor2(props.color) && !isThemeToken;
|
|
12203
|
+
applyBaseProps(stat, props);
|
|
12204
|
+
const useInlineColor = props.color && isArbitraryColor(props.color) && !statIsThemeToken;
|
|
12211
12205
|
if (props.icon) {
|
|
12212
12206
|
const figure = document.createElement("div");
|
|
12213
12207
|
figure.className = "nr-stat__figure";
|
|
@@ -12300,9 +12294,12 @@ function renderHtmlString(html) {
|
|
|
12300
12294
|
processedContent = processedContent.replace(
|
|
12301
12295
|
/<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
|
|
12302
12296
|
(_match, cssContent) => {
|
|
12297
|
+
const trimmed = cssContent.trim();
|
|
12298
|
+
const existing = document.head.querySelector("style[data-nr-global]");
|
|
12299
|
+
if (existing && existing.textContent === trimmed) return "";
|
|
12303
12300
|
const styleEl = document.createElement("style");
|
|
12304
12301
|
styleEl.setAttribute("data-nr-global", "");
|
|
12305
|
-
styleEl.textContent =
|
|
12302
|
+
styleEl.textContent = trimmed;
|
|
12306
12303
|
document.head.appendChild(styleEl);
|
|
12307
12304
|
return "";
|
|
12308
12305
|
}
|
|
@@ -12372,19 +12369,14 @@ function renderElement(element, ctx, allElements) {
|
|
|
12372
12369
|
switch (element.type) {
|
|
12373
12370
|
case "header": {
|
|
12374
12371
|
const tag = `h${element.level}`;
|
|
12375
|
-
let text = element.text;
|
|
12376
|
-
const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
|
|
12377
|
-
const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
|
|
12378
|
-
if (alignCenter) text = alignCenter[1];
|
|
12379
|
-
else if (alignRight) text = alignRight[1];
|
|
12380
12372
|
const h = document.createElement(tag);
|
|
12381
12373
|
h.id = element.id;
|
|
12382
12374
|
let cls = `md-h${element.level}`;
|
|
12383
|
-
if (
|
|
12384
|
-
if (
|
|
12375
|
+
if (element.align === "center") cls += " text-center";
|
|
12376
|
+
else if (element.align === "right") cls += " text-right";
|
|
12385
12377
|
if (element.classes) cls += ` ${element.classes}`;
|
|
12386
12378
|
h.className = cls;
|
|
12387
|
-
h.appendChild(renderInline(text));
|
|
12379
|
+
h.appendChild(renderInline(element.text));
|
|
12388
12380
|
return h;
|
|
12389
12381
|
}
|
|
12390
12382
|
case "paragraph": {
|
|
@@ -12831,7 +12823,7 @@ var guideData = [
|
|
|
12831
12823
|
"title": "Card",
|
|
12832
12824
|
"icon": "dashboard",
|
|
12833
12825
|
"order": 1,
|
|
12834
|
-
"md": '# Card\n\nLa directiva `:::card` crea una tarjeta con icono, t\xEDtulo y contenido markdown.\n\n## Sintaxis b\xE1sica\n\
|
|
12826
|
+
"md": '# Card\n\nLa directiva `:::card` crea una tarjeta con icono, t\xEDtulo y contenido markdown.\n\n## Sintaxis b\xE1sica\n\nEl slot `#description` es **obligatorio** para mostrar texto en la card:\n\n```md\n:::card {title="Mi proyecto" icon="rocket"}\n\n#description\nResumen corto del proyecto.\n\n:::\n```\n\n:::card {title="Mi proyecto" icon="rocket"}\n\n#description\nResumen corto del proyecto.\n\n:::\n\n## Con contenido markdown\n\nEl slot `#description` admite markdown completo:\n\n```md\n:::card {title="Documentaci\xF3n t\xE9cnica" icon="code"}\n\n#description\nGu\xEDa completa del motor de renderizado.\n\n- Renderizado por el mismo motor\n- Soporta `inline`, tablas y directivas\n:::\n```\n\n:::card {title="Documentaci\xF3n t\xE9cnica" icon="code"}\n\n#description\nGu\xEDa completa del motor de renderizado.\n\n- Renderizado por el mismo motor\n- Soporta `inline`, tablas y directivas\n:::\n\n## Grid autom\xE1tico\n\nLas tarjetas **consecutivas** se agrupan en una cuadr\xEDcula responsive. A\xF1ade `batch="off"` para evitarlo:\n\n```md\n:::card {title="HTML" icon="html"}\n\n#description\nEstructura del documento.\n:::\n:::card {title="CSS" icon="palette"}\n\n#description\nEstilos y variables.\n:::\n:::card {title="JS" icon="javascript"}\n\n#description\nInteracci\xF3n y eventos.\n:::\n```\n\n:::card {title="HTML" icon="html"}\n\n#description\nEstructura del documento.\n:::\n:::card {title="CSS" icon="palette"}\n\n#description\nEstilos y variables.\n:::\n:::card {title="JS" icon="javascript"}\n\n#description\nInteracci\xF3n y eventos.\n:::\n\n## Alineaci\xF3n del grid\n\nUsa `align` para controlar la alineaci\xF3n de las tarjetas en el grid:\n\n```md\n:::card {title="Centrada A" icon="star" align="center"}\n\n#description\nContenido.\n:::\n:::card {title="Centrada B" icon="favorite"}\n\n#description\nContenido.\n:::\n```\n\n> `align` solo se define en la primera card del grupo; las dem\xE1s lo ignoran.\n\n:::card {title="Centrada A" icon="star" align="center"}\n\n#description\nContenido.\n:::\n:::card {title="Centrada B" icon="favorite"}\n\n#description\nContenido.\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | T\xEDtulo de la tarjeta |\n| `icon` | nombre Material | Icono del t\xEDtulo |\n| `image` | URL | Imagen de banner superior |\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del grid. Solo se lee de la primera card del grupo (default `left`) |\n| `batch` | `off` | Desactiva el agrupado en grid con las tarjetas vecinas |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Slots\n\n| Slot | Descripci\xF3n |\n| --- | --- |\n| `#description` | Texto de la card. **Obligatorio** para mostrar contenido debajo del t\xEDtulo |\n\n## Anidando directivas\n\n```md\n:::card {title="Ejemplo anidado" icon="layers"}\n\n#description\nUna admonici\xF3n dentro de la tarjeta.\n\n:::note\nLas tarjetas aceptan cualquier directiva dentro.\n:::\n:::\n```\n\n:::card {title="Ejemplo anidado" icon="layers"}\n\n#description\nUna admonici\xF3n dentro de la tarjeta.\n\n:::note\nLas tarjetas aceptan cualquier directiva dentro.\n:::\n:::\n\n## Variantes\n\nExisten dos variantes de la tarjeta con comportamiento interactivo:\n\n| Directiva | Comportamiento al hacer click |\n| --- | --- |\n| `:::card` | Sin acci\xF3n (tarjeta est\xE1tica) |\n| `:::card-m` | Abre un modal con el contenido del slot `#content` |\n| `:::card-b` | Navega a la URL indicada en la prop `url` |\n\nLas tres variantes comparten las mismas props base (`title`, `icon`, `image`) y se agrupan autom\xE1ticamente en grid. Consulta las p\xE1ginas de **Card Modal** y **Card Link** para m\xE1s detalles.'
|
|
12835
12827
|
},
|
|
12836
12828
|
{
|
|
12837
12829
|
"id": "card-m",
|
|
@@ -12839,7 +12831,7 @@ var guideData = [
|
|
|
12839
12831
|
"title": "Card Modal",
|
|
12840
12832
|
"icon": "open_in_new",
|
|
12841
12833
|
"order": 2,
|
|
12842
|
-
"md": '# Card Modal\r\n\r\nLa directiva `:::card-m` crea una tarjeta interactiva que al hacer click abre un **modal** con contenido detallado.\r\n\r\n## Sintaxis\r\n\r\n```md\r\n:::card-m {title="Mi proyecto" icon="rocket"}\r\n\r\n#
|
|
12834
|
+
"md": '# Card Modal\r\n\r\nLa directiva `:::card-m` crea una tarjeta interactiva que al hacer click abre un **modal** con contenido detallado.\r\n\r\n## Sintaxis\r\n\r\n```md\r\n:::card-m {title="Mi proyecto" icon="rocket"}\r\n\r\n#description\r\nDescripci\xF3n breve visible en la tarjeta.\r\n\r\n#content\r\nContenido **detallado** que aparece en el modal.\r\nPuede incluir markdown completo: tablas, c\xF3digo, directivas...\r\n\r\n:::\r\n```\r\n\r\n:::card-m {title="Mi proyecto" icon="rocket"}\r\n\r\n#description\r\nDescripci\xF3n breve visible en la tarjeta.\r\n\r\n#content\r\nContenido **detallado** que aparece en el modal.\r\nPuede incluir markdown completo: tablas, c\xF3digo, directivas...\r\n\r\n:::\r\n\r\n## Con imagen\r\n\r\n```md\r\n:::card-m {title="Paisaje" image="https://img.daisyui.com/images/stock/photo-1506905925346-21bda4d32df4.webp"}\r\n\r\n#description\r\nUna vista impresionante de las monta\xF1as.\r\n\r\n#content\r\n## Detalles del paisaje\r\n\r\n- Ubicaci\xF3n: Alpes suizos\r\n- Altitud: 2.500m\r\n- Mejor \xE9poca: Junio\u2013Septiembre\r\n\r\n:::\r\n```\r\n\r\n:::card-m {title="Paisaje" image="https://img.daisyui.com/images/stock/photo-1506905925346-21bda4d32df4.webp"}\r\n\r\n#description\r\nUna vista impresionante de las monta\xF1as.\r\n\r\n#content\r\n## Detalles del paisaje\r\n\r\n- Ubicaci\xF3n: Alpes suizos\r\n- Altitud: 2.500m\r\n- Mejor \xE9poca: Junio\u2013Septiembre\r\n\r\n:::\r\n\r\n## Con slot `#description`\r\n\r\n```md\r\n:::card-m {title="Estad\xEDsticas" icon="analytics"}\r\n\r\n#description\r\nResumen r\xE1pido del rendimiento.\r\n\r\n#content\r\n| M\xE9trica | Valor |\r\n| --- | --- |\r\n| Usuarios | 12.345 |\r\n| Tasa de conversi\xF3n | 3,2% |\r\n| Tiempo medio | 2m 15s |\r\n\r\n:::\r\n```\r\n\r\n:::card-m {title="Estad\xEDsticas" icon="analytics"}\r\n\r\n#description\r\nResumen r\xE1pido del rendimiento.\r\n\r\n#content\r\n| M\xE9trica | Valor |\r\n| --- | --- |\r\n| Usuarios | 12.345 |\r\n| Tasa de conversi\xF3n | 3,2% |\r\n| Tiempo medio | 2m 15s |\r\n\r\n:::\r\n\r\n## Grid autom\xE1tico\r\n\r\nLas cards `:::card-m` se agrupan en grid con `:::card` y `:::card-b`. Usa `batch="off"` para evitarlo:\r\n\r\n```md\r\n:::card {title="Est\xE1tica" icon="info"}\r\nContenido siempre visible.\r\n:::\r\n:::card-m {title="Modal" icon="open_in_new"}\r\nClick para ver m\xE1s.\r\n:::\r\n:::card-b {title="Link" icon="link" url="https://example.com"}\r\nAbre en nueva pesta\xF1a.\r\n:::\r\n```\r\n\r\n:::card {title="Est\xE1tica" icon="info"}\r\nContenido siempre visible.\r\n:::\r\n:::card-m {title="Modal" icon="open_in_new"}\r\nClick para ver m\xE1s.\r\n:::\r\n:::card-b {title="Link" icon="link" url="https://example.com"}\r\nAbre en nueva pesta\xF1a.\r\n:::\r\n\r\n## Props\r\n\r\n| Prop | Tipo | Descripci\xF3n |\r\n| --- | --- | --- |\r\n| `title` | texto | T\xEDtulo de la tarjeta |\r\n| `icon` | nombre Material | Icono del t\xEDtulo |\r\n| `image` | URL | Imagen de banner superior |\r\n| `url` | URL | URL opcional (no se usa como link, solo metadata) |\r\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del grid. Solo se lee de la primera card del grupo (default `left`) |\r\n| `batch` | `off` | Desactiva el agrupado en grid |\r\n| `class` | texto | Clases CSS adicionales |\r\n| `style` | CSS | Estilos inline |\r\n\r\n## Slots\r\n\r\n| Slot | Descripci\xF3n |\r\n| --- | --- |\r\n| `#description` | Texto de la card. **Obligatorio** para mostrar contenido debajo del t\xEDtulo |\r\n| `#content` | Contenido detallado que se muestra en el modal |\r\n\r\n## Diferencia con `:::card` y `:::card-b`\r\n\r\n| Directiva | Comportamiento al hacer click |\r\n| --- | --- |\r\n| `:::card` | Sin acci\xF3n (tarjeta est\xE1tica) |\r\n| `:::card-m` | Abre un modal con el contenido de `#content` |\r\n| `:::card-b` | Navega a la URL indicada en `url` |'
|
|
12843
12835
|
},
|
|
12844
12836
|
{
|
|
12845
12837
|
"id": "keys",
|
|
@@ -12847,7 +12839,7 @@ var guideData = [
|
|
|
12847
12839
|
"title": "Keys (teclas)",
|
|
12848
12840
|
"icon": "keyboard",
|
|
12849
12841
|
"order": 2,
|
|
12850
|
-
"md": '# Keys (teclas)\n\nLa directiva `:::keys` muestra combinaciones de teclado con apariencia de teclas f\xEDsicas.\n\n## Sintaxis\n\n```md\n:::keys\nCTRL + C\n:::\n```\n\n:::keys\nCTRL + C\n:::\n\n## Varias combinaciones\n\n```md\n:::keys\nCTRL + SHIFT + P\n:::\n```\n\n:::keys\nCTRL + SHIFT + P\n:::\n\n:::keys\nALT + F4\n:::\n\n:::keys\nESC\n:::\n\n## Tama\xF1os\n\n| Tama\xF1o | Sintaxis |\n| --- | --- |\n| `xs` | `:::keys {size="xs"}` |\n| `sm` | `:::keys {size="sm"}` |\n| `md` | sin prop (default) |\n| `lg` | `:::keys {size="lg"}` |\n| `xl` | `:::keys {size="xl"}` |\n\n:::keys {size="xs"}\nCTRL + A\n:::\n\n:::keys {size="sm"}\nCTRL + A\n:::\n\n:::keys {size="md"}\nCTRL + A\n:::\n\n:::keys {size="lg"}\nCTRL + A\n:::\n\n:::keys {size="xl"}\nCTRL + A\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `size` | `xs`
|
|
12842
|
+
"md": '# Keys (teclas)\n\nLa directiva `:::keys` muestra combinaciones de teclado con apariencia de teclas f\xEDsicas.\n\n## Sintaxis\n\n```md\n:::keys\nCTRL + C\n:::\n```\n\n:::keys\nCTRL + C\n:::\n\n## Varias combinaciones\n\n```md\n:::keys\nCTRL + SHIFT + P\n:::\n```\n\n:::keys\nCTRL + SHIFT + P\n:::\n\n:::keys\nALT + F4\n:::\n\n:::keys\nESC\n:::\n\n## Tama\xF1os\n\n| Tama\xF1o | Sintaxis |\n| --- | --- |\n| `xs` | `:::keys {size="xs"}` |\n| `sm` | `:::keys {size="sm"}` |\n| `md` | sin prop (default) |\n| `lg` | `:::keys {size="lg"}` |\n| `xl` | `:::keys {size="xl"}` |\n\n:::keys {size="xs"}\nCTRL + A\n:::\n\n:::keys {size="sm"}\nCTRL + A\n:::\n\n:::keys {size="md"}\nCTRL + A\n:::\n\n:::keys {size="lg"}\nCTRL + A\n:::\n\n:::keys {size="xl"}\nCTRL + A\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `size` | `xs` / `sm` / `md` / `lg` / `xl` | Tama\xF1o de las teclas (default `md`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Ejemplo combinado\n\n```md\n:::keys {size="lg"}\nSHIFT + CTRL + G\n:::\n```\n\n:::keys {size="lg"}\nSHIFT + CTRL + G\n:::\n\n> Las teclas se separan autom\xE1ticamente por el signo `+`.'
|
|
12851
12843
|
},
|
|
12852
12844
|
{
|
|
12853
12845
|
"id": "accordion",
|
|
@@ -12863,7 +12855,7 @@ var guideData = [
|
|
|
12863
12855
|
"title": "Card Link",
|
|
12864
12856
|
"icon": "link",
|
|
12865
12857
|
"order": 3,
|
|
12866
|
-
"md": '# Card Link\r\n\r\nLa directiva `:::card-b` crea una tarjeta interactiva que al hacer click **navega a una URL** en una nueva pesta\xF1a.\r\n\r\n## Sintaxis\r\n\r\n```md\r\n:::card-b {title="Documentaci\xF3n" icon="menu_book" url="https://example.com"}\r\n\r\n#
|
|
12858
|
+
"md": '# Card Link\r\n\r\nLa directiva `:::card-b` crea una tarjeta interactiva que al hacer click **navega a una URL** en una nueva pesta\xF1a.\r\n\r\n## Sintaxis\r\n\r\n```md\r\n:::card-b {title="Documentaci\xF3n" icon="menu_book" url="https://example.com"}\r\n\r\n#description\r\nAccede a la documentaci\xF3n completa del proyecto.\r\n\r\n:::\r\n```\r\n\r\n:::card-b {title="Documentaci\xF3n" icon="menu_book" url="https://example.com"}\r\n\r\n#description\r\nAccede a la documentaci\xF3n completa del proyecto.\r\n\r\n:::\r\n\r\n## Con imagen\r\n\r\n```md\r\n:::card-b {title="GitHub" image="https://img.daisyui.com/images/stock/photo-1470071459604-3b5ec3a7fe05.webp" url="https://github.com"}\r\n\r\n#description\r\nExplora el repositorio en GitHub.\r\n\r\n:::\r\n```\r\n\r\n:::card-b {title="GitHub" image="https://img.daisyui.com/images/stock/photo-1470071459604-3b5ec3a7fe05.webp" url="https://github.com"}\r\n\r\n#description\r\nExplora el repositorio en GitHub.\r\n\r\n:::\r\n\r\n## Con imagen y descripci\xF3n\r\n\r\n```md\r\n:::card-b {title="NPM" icon="inventory_2" image="https://img.daisyui.com/images/stock/photo-1470071459604-3b5ec3a7fe05.webp" url="https://npmjs.com"}\r\n\r\n#description\r\nPublicado recientemente con las \xFAltimas mejoras.\r\n\r\n:::\r\n```\r\n\r\n:::card-b {title="NPM" icon="inventory_2" image="https://img.daisyui.com/images/stock/photo-1470071459604-3b5ec3a7fe05.webp" url="https://npmjs.com"}\r\n\r\n#description\r\nPublicado recientemente con las \xFAltimas mejoras.\r\n\r\n:::\r\n\r\n## Grid autom\xE1tico\r\n\r\nLas cards `:::card-b` se agrupan en grid con `:::card` y `:::card-m`. Usa `batch="off"` para evitarlo:\r\n\r\n```md\r\n:::card-b {title="Docs" icon="menu_book" url="https://docs.example.com"}\r\n\r\n#description\r\nDocumentaci\xF3n oficial.\r\n:::\r\n:::card-b {title="GitHub" icon="code" url="https://github.com"}\r\n\r\n#description\r\nC\xF3digo fuente.\r\n:::\r\n:::card-b {title="NPM" icon="inventory_2" url="https://npmjs.com"}\r\n\r\n#description\r\nPaquete npm.\r\n:::\r\n```\r\n\r\n## Props\r\n\r\n| Prop | Tipo | Descripci\xF3n |\r\n| --- | --- | --- |\r\n| `title` | texto | T\xEDtulo de la tarjeta |\r\n| `icon` | nombre Material | Icono del t\xEDtulo |\r\n| `image` | URL | Imagen de banner superior |\r\n| `url` | URL | **Requerido.** URL de destino al hacer click |\r\n| `target` | texto | Target del enlace (por defecto `_blank`) |\r\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del grid. Solo se lee de la primera card del grupo (default `left`) |\r\n| `batch` | `off` | Desactiva el agrupado en grid |\r\n| `class` | texto | Clases CSS adicionales |\r\n| `style` | CSS | Estilos inline |\r\n\r\n## Slots\r\n\r\n| Slot | Descripci\xF3n |\r\n| --- | --- |\r\n| `#description` | Texto de la card. **Obligatorio** para mostrar contenido debajo del t\xEDtulo |\r\n\r\n## Diferencia con `:::card` y `:::card-m`\r\n\r\n| Directiva | Comportamiento al hacer click |\r\n| --- | --- |\r\n| `:::card` | Sin acci\xF3n (tarjeta est\xE1tica) |\r\n| `:::card-m` | Abre un modal con el contenido de `#content` |\r\n| `:::card-b` | Navega a la URL indicada en `url` |'
|
|
12867
12859
|
},
|
|
12868
12860
|
{
|
|
12869
12861
|
"id": "carousel",
|
|
@@ -12871,7 +12863,7 @@ var guideData = [
|
|
|
12871
12863
|
"title": "Carousel",
|
|
12872
12864
|
"icon": "view_carousel",
|
|
12873
12865
|
"order": 4,
|
|
12874
|
-
"md": '# Carousel\n\nLa directiva `:::carousel` muestra un carrusel de im\xE1genes con flechas, puntos de navegaci\xF3n y **loop infinito**.\n\n## Sintaxis\n\nLas im\xE1genes se ponen como markdown dentro del bloque:\n\n```md\n:::carousel {height="320px"}\n\n\n\n\n:::\n```\n\n:::carousel {height="320px"}\n\n\n\n\n:::\n\n## Tama\xF1o y proporci\xF3n\n\n- Sin props, el viewport usa `16/9` de aspecto.\n- `height` fija la altura del viewport (las im\xE1genes lo rellenan).\n- `aspect` fija la proporci\xF3n (`4/3`, `1/1`, `21/9`...).\n\n```md\n:::carousel {aspect="4/3" width="420px" float="right"}\n\n\n:::\n```\n\n:::carousel {aspect="4/3" width="420px" float="right"}\n\n\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `height` | CSS (px) | Altura fija del viewport |\n| `aspect` | ratio | Proporci\xF3n del viewport (default `16/9`) |\n| `width` | CSS (px, %) | Ancho del carrusel |\n| `float` | `left`
|
|
12866
|
+
"md": '# Carousel\n\nLa directiva `:::carousel` muestra un carrusel de im\xE1genes con flechas, puntos de navegaci\xF3n y **loop infinito**.\n\n## Sintaxis\n\nLas im\xE1genes se ponen como markdown dentro del bloque:\n\n```md\n:::carousel {height="320px"}\n\n\n\n\n:::\n```\n\n:::carousel {height="320px"}\n\n\n\n\n:::\n\n## Tama\xF1o y proporci\xF3n\n\n- Sin props, el viewport usa `16/9` de aspecto.\n- `height` fija la altura del viewport (las im\xE1genes lo rellenan).\n- `aspect` fija la proporci\xF3n (`4/3`, `1/1`, `21/9`...).\n\n```md\n:::carousel {aspect="4/3" width="420px" float="right"}\n\n\n:::\n```\n\n:::carousel {aspect="4/3" width="420px" float="right"}\n\n\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `height` | CSS (px) | Altura fija del viewport |\n| `aspect` | ratio | Proporci\xF3n del viewport (default `16/9`) |\n| `width` | CSS (px, %) | Ancho del carrusel |\n| `float` | `left` / `right` / `center` | Flotaci\xF3n (sin `width`, el flotante usa `max-width: 50%`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Interacci\xF3n\n\n- **Flechas** (izquierda/derecha): navegar.\n- **Puntos** inferiores: ir a una imagen.\n- **Teclado**: `\u2190` y `\u2192` cuando el carrusel est\xE1 enfocado.\n- El carrusel **da la vuelta** al llegar al final (loop infinito).\n\n> Las im\xE1genes se recortan (`object-fit: cover`) para rellenar el viewport sin deformarse.'
|
|
12875
12867
|
},
|
|
12876
12868
|
{
|
|
12877
12869
|
"id": "countdown",
|
|
@@ -12887,7 +12879,7 @@ var guideData = [
|
|
|
12887
12879
|
"title": "Diff (comparar im\xE1genes)",
|
|
12888
12880
|
"icon": "compare",
|
|
12889
12881
|
"order": 6,
|
|
12890
|
-
"md": '# Diff (comparar im\xE1genes)\n\nLa directiva `:::diff` muestra **antes y despu\xE9s** con un slider arrastrable.\n\n## Sintaxis\n\nSe indican las dos im\xE1genes con las props `before` y `after`:\n\n```md\n:::diff {before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n```\n\n:::diff {before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n\n## Con dos im\xE1genes markdown\n\nAlternativa: dos im\xE1genes en el cuerpo del bloque (la primera es el \xABantes\xBB):\n\n```md\n:::diff {height="320px"}\n\n\n:::\n```\n\n:::diff {height="320px"}\n\n\n:::\n\n## Tama\xF1o y flotaci\xF3n\n\n```md\n:::diff {width="440px" aspect="4/3" float="left" before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n```\n\n:::diff {width="440px" aspect="4/3" float="left" before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n\nTexto que fluye junto al diff flotante: la comparaci\xF3n queda integrada en el p\xE1rrafo como una imagen flotante m\xE1s.\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `before` | URL | Imagen \xABantes\xBB (descartada si hay dos im\xE1genes markdown) |\n| `after` | URL | Imagen \xABdespu\xE9s\xBB |\n| `height` | CSS (px) | Altura del comparador (default `16/9` de aspecto) |\n| `aspect` | ratio | Proporci\xF3n (`4/3`, `1/1`, ...) |\n| `width` | CSS (px, %) | Ancho del comparador |\n| `float` | `left`
|
|
12882
|
+
"md": '# Diff (comparar im\xE1genes)\n\nLa directiva `:::diff` muestra **antes y despu\xE9s** con un slider arrastrable.\n\n## Sintaxis\n\nSe indican las dos im\xE1genes con las props `before` y `after`:\n\n```md\n:::diff {before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n```\n\n:::diff {before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n\n## Con dos im\xE1genes markdown\n\nAlternativa: dos im\xE1genes en el cuerpo del bloque (la primera es el \xABantes\xBB):\n\n```md\n:::diff {height="320px"}\n\n\n:::\n```\n\n:::diff {height="320px"}\n\n\n:::\n\n## Tama\xF1o y flotaci\xF3n\n\n```md\n:::diff {width="440px" aspect="4/3" float="left" before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n```\n\n:::diff {width="440px" aspect="4/3" float="left" before="https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp" after="https://img.daisyui.com/images/stock/photo-1572635196237-14b3f281503f.webp"}\n:::\n\nTexto que fluye junto al diff flotante: la comparaci\xF3n queda integrada en el p\xE1rrafo como una imagen flotante m\xE1s.\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `before` | URL | Imagen \xABantes\xBB (descartada si hay dos im\xE1genes markdown) |\n| `after` | URL | Imagen \xABdespu\xE9s\xBB |\n| `height` | CSS (px) | Altura del comparador (default `16/9` de aspecto) |\n| `aspect` | ratio | Proporci\xF3n (`4/3`, `1/1`, ...) |\n| `width` | CSS (px, %) | Ancho del comparador |\n| `float` | `left` / `right` / `center` | Flotaci\xF3n (sin `width`, `max-width: 50%`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Interacci\xF3n\n\n- **Arrastra** el mango vertical para mover la l\xEDnea de corte.\n- **Haz clic** en cualquier punto para saltar el slider all\xED.\n- **Teclado**: `\u2190` y `\u2192` ajustan \xB15% (enfoca el comparador con Tab).'
|
|
12891
12883
|
},
|
|
12892
12884
|
{
|
|
12893
12885
|
"id": "hover-3d",
|
|
@@ -12911,7 +12903,7 @@ var guideData = [
|
|
|
12911
12903
|
"title": "Chat",
|
|
12912
12904
|
"icon": "chat_bubble",
|
|
12913
12905
|
"order": 9,
|
|
12914
|
-
"md": '# Chat\n\nLa directiva `:::chat` muestra **burbujas de conversaci\xF3n** (`:::chat-item`) estilo app de mensajer\xEDa.\n\n## Sintaxis\n\n```md\n:::chat\n:::chat-item {side="start" name="Ana" time="10:04"}\nHola, \xBFterminaste la documentaci\xF3n?\n:::\n:::chat-item {side="end" name="T\xFA" time="10:05"}\n\xA1S\xED! La gu\xEDa renderiza hasta directivas dentro del chat.\n:::\n:::chat-item {side="start" name="Ana" time="10:06"}\nIncre\xEDble. El motor escribe solo.\n:::\n:::\n```\n\n:::chat\n:::chat-item {side="start" name="Ana" time="10:04"}\nHola, \xBFterminaste la documentaci\xF3n?\n:::\n:::chat-item {side="end" name="T\xFA" time="10:05"}\n\xA1S\xED! La gu\xEDa renderiza hasta directivas dentro del chat.\n:::\n:::chat-item {side="start" name="Ana" time="10:06"}\nIncre\xEDble. El motor escribe solo.\n:::\n:::\n\n## Con avatar y color\n\n```md\n:::chat\n:::chat-item {side="start" name="Soporte" time="11:00" avatar="https://img.daisyui.com/images/stock/photo-1534528741775-53994a69daeb.webp" color="info" footer="Atendido"}\n\xBFEn qu\xE9 podemos ayudarte?\n:::\n:::chat-item {side="end" name="T\xFA" time="11:02" color="secondary" footer="Enviado"}\n\xBFC\xF3mo a\xF1ado un avatar personalizado?\n:::\n:::\n```\n\n:::chat\n:::chat-item {side="start" name="Soporte" time="11:00" avatar="https://img.daisyui.com/images/stock/photo-1534528741775-53994a69daeb.webp" color="info" footer="Atendido"}\n\xBFEn qu\xE9 podemos ayudarte?\n:::\n:::chat-item {side="end" name="T\xFA" time="11:02" color="secondary" footer="Enviado"}\n\xBFC\xF3mo a\xF1ado un avatar personalizado?\n:::\n:::\n\n## Props\n\n### `:::chat-item`\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `side` | `start` \\| `end` | Burbuja a la izquierda o derecha (default `start`) |\n| `name` | texto | Nombre del autor |\n| `time` | texto | Hora mostrada bajo el nombre |\n| `avatar` | URL | Imagen del avatar |\n| `color` | `neutral`
|
|
12906
|
+
"md": '# Chat\n\nLa directiva `:::chat` muestra **burbujas de conversaci\xF3n** (`:::chat-item`) estilo app de mensajer\xEDa.\n\n## Sintaxis\n\n```md\n:::chat\n:::chat-item {side="start" name="Ana" time="10:04"}\nHola, \xBFterminaste la documentaci\xF3n?\n:::\n:::chat-item {side="end" name="T\xFA" time="10:05"}\n\xA1S\xED! La gu\xEDa renderiza hasta directivas dentro del chat.\n:::\n:::chat-item {side="start" name="Ana" time="10:06"}\nIncre\xEDble. El motor escribe solo.\n:::\n:::\n```\n\n:::chat\n:::chat-item {side="start" name="Ana" time="10:04"}\nHola, \xBFterminaste la documentaci\xF3n?\n:::\n:::chat-item {side="end" name="T\xFA" time="10:05"}\n\xA1S\xED! La gu\xEDa renderiza hasta directivas dentro del chat.\n:::\n:::chat-item {side="start" name="Ana" time="10:06"}\nIncre\xEDble. El motor escribe solo.\n:::\n:::\n\n## Con avatar y color\n\n```md\n:::chat\n:::chat-item {side="start" name="Soporte" time="11:00" avatar="https://img.daisyui.com/images/stock/photo-1534528741775-53994a69daeb.webp" color="info" footer="Atendido"}\n\xBFEn qu\xE9 podemos ayudarte?\n:::\n:::chat-item {side="end" name="T\xFA" time="11:02" color="secondary" footer="Enviado"}\n\xBFC\xF3mo a\xF1ado un avatar personalizado?\n:::\n:::\n```\n\n:::chat\n:::chat-item {side="start" name="Soporte" time="11:00" avatar="https://img.daisyui.com/images/stock/photo-1534528741775-53994a69daeb.webp" color="info" footer="Atendido"}\n\xBFEn qu\xE9 podemos ayudarte?\n:::\n:::chat-item {side="end" name="T\xFA" time="11:02" color="secondary" footer="Enviado"}\n\xBFC\xF3mo a\xF1ado un avatar personalizado?\n:::\n:::\n\n## Props\n### `:::chat`\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n### `:::chat-item`\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `side` | `start` \\| `end` | Burbuja a la izquierda o derecha (default `start`) |\n| `name` | texto | Nombre del autor |\n| `time` | texto | Hora mostrada bajo el nombre |\n| `avatar` | URL | Imagen del avatar |\n| `color` | `neutral` / `primary` / `secondary` / `accent` / `info` / `success` / `warning` / `error` / CSS color | Color de la burbuja. Acepta tokens del tema o cualquier color CSS v\\u00e1lido (ej: `blue`, `#ff6600`, `rgb(255,0,0)`) |\n| `footer` | texto | Pie del mensaje |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Notas\n\n- El contenido de cada `chat-item` admite **markdown completo** (c\xF3digo, tablas, enlaces...).\n- Puedes poner varios `:::chat` en el documento; cada uno es un grupo independiente.'
|
|
12915
12907
|
},
|
|
12916
12908
|
{
|
|
12917
12909
|
"id": "richlist",
|
|
@@ -12927,7 +12919,7 @@ var guideData = [
|
|
|
12927
12919
|
"title": "Stat",
|
|
12928
12920
|
"icon": "insights",
|
|
12929
12921
|
"order": 11,
|
|
12930
|
-
"md": '# Stat\n\nLa directiva `:::stat` muestra una **estad\xEDstica** con icono, valor y descripci\xF3n. Las estad\xEDsticas **consecutivas** se agrupan en una fila.\n\n## Sintaxis\n\n```md\n:::stat {title="Descargas" value="31K" icon="download" color="success"}\n:::\n:::stat {title="Nuevos usuarios" value="4,200" icon="group_add" color="primary"}\n:::\n:::stat {title="Retenci\xF3n" value="82%" icon="trending_up" color="info"}\n:::\n```\n\n:::stat {title="Descargas" value="31K" icon="download" color="success"}\n:::\n:::stat {title="Nuevos usuarios" value="4,200" icon="group_add" color="primary"}\n:::\n:::stat {title="Retenci\xF3n" value="82%" icon="trending_up" color="info"}\n:::\n\n## Con descripci\xF3n\n\n```md\n:::stat {title="Ingresos" value="$14,320" desc="+12% este mes" icon="payments" color="secondary"}\n:::\n:::stat {title="Errores" value="3" desc="resueltos hoy" icon="bug_report" color="warning"}\n:::\n```\n\n:::stat {title="Ingresos" value="$14,320" desc="+12% este mes" icon="payments" color="secondary"}\n:::\n:::stat {title="Errores" value="3" desc="resueltos hoy" icon="bug_report" color="warning"}\n:::\n\n## Prop individual (sin agrupar)\n\n```md\n:::stat {title="Tiempo de actividad" value="99.9%" icon="monitor_heart" color="success"}\n:::\n```\n\n:::stat {title="Tiempo de actividad" value="99.9%" icon="monitor_heart" color="success"}\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | Etiqueta superior |\n| `value` | texto | Valor principal (grande) |\n| `desc` | texto | Descripci\xF3n bajo el valor |\n| `icon` | nombre Material | Icono lateral |\n| `color` | `primary`
|
|
12922
|
+
"md": '# Stat\n\nLa directiva `:::stat` muestra una **estad\xEDstica** con icono, valor y descripci\xF3n. Las estad\xEDsticas **consecutivas** se agrupan en una fila.\n\n## Sintaxis\n\n```md\n:::stat {title="Descargas" value="31K" icon="download" color="success"}\n:::\n:::stat {title="Nuevos usuarios" value="4,200" icon="group_add" color="primary"}\n:::\n:::stat {title="Retenci\xF3n" value="82%" icon="trending_up" color="info"}\n:::\n```\n\n:::stat {title="Descargas" value="31K" icon="download" color="success"}\n:::\n:::stat {title="Nuevos usuarios" value="4,200" icon="group_add" color="primary"}\n:::\n:::stat {title="Retenci\xF3n" value="82%" icon="trending_up" color="info"}\n:::\n\n## Con descripci\xF3n\n\n```md\n:::stat {title="Ingresos" value="$14,320" desc="+12% este mes" icon="payments" color="secondary"}\n:::\n:::stat {title="Errores" value="3" desc="resueltos hoy" icon="bug_report" color="warning"}\n:::\n```\n\n:::stat {title="Ingresos" value="$14,320" desc="+12% este mes" icon="payments" color="secondary"}\n:::\n:::stat {title="Errores" value="3" desc="resueltos hoy" icon="bug_report" color="warning"}\n:::\n\n## Prop individual (sin agrupar)\n\n```md\n:::stat {title="Tiempo de actividad" value="99.9%" icon="monitor_heart" color="success"}\n:::\n```\n\n:::stat {title="Tiempo de actividad" value="99.9%" icon="monitor_heart" color="success"}\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | Etiqueta superior |\n| `value` | texto | Valor principal (grande) |\n| `desc` | texto | Descripci\xF3n bajo el valor |\n| `icon` | nombre Material | Icono lateral |\n| `color` | `primary` / `secondary` / `info` / `success` / `warning` / `error` / CSS color | Color del icono y valor. Acepta tokens del tema o cualquier color CSS v\\u00e1lido (ej: `blue`, `#ff0000`, `rgb(255,0,0)`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n> Cada `:::stat` debe cerrarse con su `:::`. Las stats contiguas se agrupan en fila autom\xE1ticamente; para separarlas deja texto entre medias.'
|
|
12931
12923
|
},
|
|
12932
12924
|
{
|
|
12933
12925
|
"id": "details",
|
|
@@ -12935,7 +12927,7 @@ var guideData = [
|
|
|
12935
12927
|
"title": "Details",
|
|
12936
12928
|
"icon": "expand_more",
|
|
12937
12929
|
"order": 1,
|
|
12938
|
-
"md": '# Details\n\nLa directiva `:::details` crea un bloque **plegable** nativo (`<details>`), \xFAtil para respuestas largas o contenido oculto.\n\n## Sintaxis\n\n```md\n:::details {title="\xBFQu\xE9 es NoirMD?"}\nEditor y motor de markdown con directivas propias.\n:::\n```\n\n:::details {title="\xBFQu\xE9 es NoirMD?"}\nEditor y motor de markdown con directivas propias.\n:::\n\n## Abierto por defecto\n\n```md\n:::details {title="Atajos del editor" defaultOpen="true"}\n| Atajo | Acci\xF3n |\n| --- | --- |\n| `Ctrl+S` | Guardar |\n| `Ctrl+K` | Alternar preview |\n| `Ctrl+F` | Buscar |\n:::\n```\n\n:::details {title="Atajos del editor" defaultOpen="true"}\n| Atajo | Acci\xF3n |\n| --- | --- |\n| `Ctrl+S` | Guardar |\n| `Ctrl+K` | Alternar preview |\n| `Ctrl+F` | Buscar |\n:::\n\n## Con icono\n\n```md\n:::details {title="Soluci\xF3n del ejercicio" icon="lightbulb"}\nEl c\xF3digo resultante:\n\n```js\nconsole.log(\'\xA1Resuelto!\');\n```\n:::\n```\n\n:::details {title="Soluci\xF3n del ejercicio" icon="lightbulb"}\nEl c\xF3digo resultante:\n\n```js\nconsole.log(\'\xA1Resuelto!\');\n```\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | T
|
|
12930
|
+
"md": '# Details\n\nLa directiva `:::details` crea un bloque **plegable** nativo (`<details>`), \xFAtil para respuestas largas o contenido oculto.\n\n## Sintaxis\n\n```md\n:::details {title="\xBFQu\xE9 es NoirMD?"}\nEditor y motor de markdown con directivas propias.\n:::\n```\n\n:::details {title="\xBFQu\xE9 es NoirMD?"}\nEditor y motor de markdown con directivas propias.\n:::\n\n## Abierto por defecto\n\n```md\n:::details {title="Atajos del editor" defaultOpen="true"}\n| Atajo | Acci\xF3n |\n| --- | --- |\n| `Ctrl+S` | Guardar |\n| `Ctrl+K` | Alternar preview |\n| `Ctrl+F` | Buscar |\n:::\n```\n\n:::details {title="Atajos del editor" defaultOpen="true"}\n| Atajo | Acci\xF3n |\n| --- | --- |\n| `Ctrl+S` | Guardar |\n| `Ctrl+K` | Alternar preview |\n| `Ctrl+F` | Buscar |\n:::\n\n## Con icono\n\n```md\n:::details {title="Soluci\xF3n del ejercicio" icon="lightbulb"}\nEl c\xF3digo resultante:\n\n```js\nconsole.log(\'\xA1Resuelto!\');\n```\n:::\n```\n\n:::details {title="Soluci\xF3n del ejercicio" icon="lightbulb"}\nEl c\xF3digo resultante:\n\n```js\nconsole.log(\'\xA1Resuelto!\');\n```\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | T\\u00edtulo del desplegable (default `Details`) |\n| `icon` | nombre Material | Icono junto al t\\u00edtulo (default `play_arrow`) |\n| `defaultOpen` | `true` | Abierto al cargar |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n> El contenido admite markdown completo y directivas anidadas.'
|
|
12939
12931
|
},
|
|
12940
12932
|
{
|
|
12941
12933
|
"id": "modal",
|
|
@@ -12943,7 +12935,7 @@ var guideData = [
|
|
|
12943
12935
|
"title": "Modal",
|
|
12944
12936
|
"icon": "open_in_full",
|
|
12945
12937
|
"order": 2,
|
|
12946
|
-
"md": '# Modal\n\nLa directiva `:::modal` crea un **di\xE1logo modal** con su bot\xF3n de apertura.\n\n## Sintaxis\n\n```md\n:::modal {title="Confirmar borrado" label="Abrir modal" icon="delete"}\n\xBFSeguro que quieres borrar este documento? Esta acci\xF3n no se puede deshacer.\n\n| Acci\xF3n | Efecto |\n| --- | --- |\n| Aceptar | Borra el documento |\n| Cancelar | No hace nada |\n:::\n```\n\n:::modal {title="Confirmar borrado" label="Abrir modal" icon="delete"}\n\xBFSeguro que quieres borrar este documento? Esta acci\xF3n no se puede deshacer.\n\n| Acci\xF3n | Efecto |\n| --- | --- |\n| Aceptar | Borra el documento |\n| Cancelar | No hace nada |\n:::\n\n## Contenido enriquecido\n\n```md\n:::modal {title="Notas de la versi\xF3n" label="Ver novedades" icon="new_releases"}\n**v2.0** \u2014 cambios principales:\n\n- Nuevo componente `:::diff`\n- Gu\xEDa integrada en el editor\n- Especificidad CSS corregida en im\xE1genes\n:::\n```\n\n:::modal {title="Notas de la versi\xF3n" label="Ver novedades" icon="new_releases"}\n**v2.0** \u2014 cambios principales:\n\n- Nuevo componente `:::diff`\n- Gu\xEDa integrada en el editor\n- Especificidad CSS corregida en im\xE1genes\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | T\xEDtulo del modal |\n| `label` | texto | Texto del bot\xF3n de apertura (
|
|
12938
|
+
"md": '# Modal\n\nLa directiva `:::modal` crea un **di\xE1logo modal** con su bot\xF3n de apertura.\n\n## Sintaxis\n\n```md\n:::modal {title="Confirmar borrado" label="Abrir modal" icon="delete"}\n\xBFSeguro que quieres borrar este documento? Esta acci\xF3n no se puede deshacer.\n\n| Acci\xF3n | Efecto |\n| --- | --- |\n| Aceptar | Borra el documento |\n| Cancelar | No hace nada |\n:::\n```\n\n:::modal {title="Confirmar borrado" label="Abrir modal" icon="delete"}\n\xBFSeguro que quieres borrar este documento? Esta acci\xF3n no se puede deshacer.\n\n| Acci\xF3n | Efecto |\n| --- | --- |\n| Aceptar | Borra el documento |\n| Cancelar | No hace nada |\n:::\n\n## Contenido enriquecido\n\n```md\n:::modal {title="Notas de la versi\xF3n" label="Ver novedades" icon="new_releases"}\n**v2.0** \u2014 cambios principales:\n\n- Nuevo componente `:::diff`\n- Gu\xEDa integrada en el editor\n- Especificidad CSS corregida en im\xE1genes\n:::\n```\n\n:::modal {title="Notas de la versi\xF3n" label="Ver novedades" icon="new_releases"}\n**v2.0** \u2014 cambios principales:\n\n- Nuevo componente `:::diff`\n- Gu\xEDa integrada en el editor\n- Especificidad CSS corregida en im\xE1genes\n:::\n\n## Alineaci\xF3n del bot\xF3n\n\nEl bot\xF3n de apertura se alinea a la izquierda por defecto. Usa el prop `align` para cambiar la alineaci\xF3n:\n\n### Centrado\n\n```md\n:::modal {title="Centrado" label="Abrir" icon="open_in_full" align="center"}\nContenido del modal centrado.\n:::\n```\n\n:::modal {title="Centrado" label="Abrir" icon="open_in_full" align="center"}\nContenido del modal centrado.\n:::\n\n### Alineado a la derecha\n\n```md\n:::modal {title="Derecha" label="Abrir" icon="open_in_full" align="right"}\nContenido del modal alineado a la derecha.\n:::\n```\n\n:::modal {title="Derecha" label="Abrir" icon="open_in_full" align="right"}\nContenido del modal alineado a la derecha.\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `title` | texto | T\xEDtulo del modal |\n| `label` (o `title`) | texto | Texto del bot\xF3n de apertura (`title` funciona como alias, default: \xABOpen\xBB) |\n| `icon` | nombre Material | Icono del bot\xF3n (default `open_in_new`) |\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del bot\xF3n de apertura (default `left`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Interacci\xF3n\n\n- **Bot\xF3n**: abre el modal (focus se mueve dentro).\n- **Overlay** o bot\xF3n **\xD7**: cierra.\n- **Esc**: cierra (en desktop).\n- `dialog` nativo \u2192 accesible por defecto, focus trapped y `inert` al fondo.'
|
|
12947
12939
|
},
|
|
12948
12940
|
{
|
|
12949
12941
|
"id": "button",
|
|
@@ -12951,7 +12943,7 @@ var guideData = [
|
|
|
12951
12943
|
"title": "Button",
|
|
12952
12944
|
"icon": "touch_app",
|
|
12953
12945
|
"order": 3,
|
|
12954
|
-
"md": '# Button\n\nLa directiva `:::button` crea un **bot\xF3n con enlace** (se abre en pesta\xF1a nueva por defecto).\n\n## Sintaxis\n\n```md\n:::button {label="Documentaci\xF3n" url="https://example.com" icon="menu_book"}\n:::\n```\n\n:::button {label="Documentaci\xF3n" url="https://example.com" icon="menu_book"}\n:::\n\n## Variante con enlace interno\n\n```md\n:::button {label="Ir a la p\xE1gina de notas" url="#admonici\xF3n-nota" icon="sticky_note_2" target="_self"}\n:::\n```\n\n:::button {label="Ir a la p\xE1gina de notas" url="#admonici\xF3n-nota" icon="sticky_note_2" target="_self"}\n:::\n\n## Con contenido markdown\n\nSi el bloque contiene texto/enlaces, se renderizan dentro del bot\xF3n:\n\n```md\n:::button {label="Descargar" url="https://example.com/download" icon="download"}\nDescarga el **manual** en PDF\n:::\n```\n\n:::button {label="Descargar" url="https://example.com/download" icon="download"}\nDescarga el **manual** en PDF\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `label` | texto | Texto del bot\xF3n |\n| `url` (o `href`) | URL | Destino del enlace (default `#`) |\n| `icon` | nombre Material | Icono (default `near_me`) |\n| `target` | `_blank`
|
|
12946
|
+
"md": '# Button\n\nLa directiva `:::button` crea un **bot\xF3n con enlace** (se abre en pesta\xF1a nueva por defecto).\n\n## Sintaxis\n\n```md\n:::button {label="Documentaci\xF3n" url="https://example.com" icon="menu_book"}\n:::\n```\n\n:::button {label="Documentaci\xF3n" url="https://example.com" icon="menu_book"}\n:::\n\n## Variante con enlace interno\n\n```md\n:::button {label="Ir a la p\xE1gina de notas" url="#admonici\xF3n-nota" icon="sticky_note_2" target="_self"}\n:::\n```\n\n:::button {label="Ir a la p\xE1gina de notas" url="#admonici\xF3n-nota" icon="sticky_note_2" target="_self"}\n:::\n\n## Con contenido markdown\n\nSi el bloque contiene texto/enlaces, se renderizan dentro del bot\xF3n:\n\n```md\n:::button {label="Descargar" url="https://example.com/download" icon="download"}\nDescarga el **manual** en PDF\n:::\n```\n\n:::button {label="Descargar" url="https://example.com/download" icon="download"}\nDescarga el **manual** en PDF\n:::\n\n## Alineaci\xF3n\n\nLos botones se alinean a la izquierda por defecto. Usa el prop `align` para cambiar la alineaci\xF3n:\n\n### Centrado\n\n```md\n:::button {label="Centrado" url="https://example.com" icon="center_focus_strong" align="center"}\n:::\n```\n\n:::button {label="Centrado" url="https://example.com" icon="center_focus_strong" align="center"}\n:::\n\n### Alineado a la derecha\n\n```md\n:::button {label="Derecha" url="https://example.com" icon="arrow_forward" align="right"}\n:::\n```\n\n:::button {label="Derecha" url="https://example.com" icon="arrow_forward" align="right"}\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `label` (o `title`) | texto | Texto del bot\xF3n (`title` funciona como alias por compatibilidad) |\n| `url` (o `href`) | URL | Destino del enlace (default `#`) |\n| `icon` | nombre Material | Icono (default `near_me`) |\n| `target` | `_blank` / `_self` / ... | Destino del enlace (default `_blank`) |\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del bot\xF3n (default `left`) |\n| `class` | texto | Clases CSS adicionales |'
|
|
12955
12947
|
},
|
|
12956
12948
|
{
|
|
12957
12949
|
"id": "slide",
|
|
@@ -12959,7 +12951,7 @@ var guideData = [
|
|
|
12959
12951
|
"title": "Slide",
|
|
12960
12952
|
"icon": "slideshow",
|
|
12961
12953
|
"order": 4,
|
|
12962
|
-
"md": '# Slide\n\nLa directiva `:::slide` convierte su contenido en un **slider autom\xE1tico** (diapositivas con fade).\n\n## Sintaxis\n\nLas secciones se separan con `---`:\n\n```md\n:::slide {interval="2500"}\n## Diapositiva 1\n\nBienvenido a la **gu\xEDa interactiva**.\n\n---\n\n## Diapositiva 2\n\nCada `---` separa una diapositiva nueva.\n\n---\n\n## Diapositiva 3\n\nY el motor se encarga del resto.\n:::\n```\n\n:::slide {interval="2500"}\n## Diapositiva 1\n\nBienvenido a la **gu\xEDa interactiva**.\n\n---\n\n## Diapositiva 2\n\nCada `---` separa una diapositiva nueva.\n\n---\n\n## Diapositiva 3\n\nY el motor se encarga del resto.\n:::\n\n## Con contenido variado\n\n```md\n:::slide {interval="3500" speed="800"}\n:::card {title="Card" icon="dashboard"}\nLas directivas se anidan dentro.\n:::\n---\n> **Admonici\xF3n** como diapositiva\n---\n| P\xE1gina | Tema |\n| --- | --- |\n| 1 | Slide |\n| 2 | Loop |\n:::\n```\n\n:::slide {interval="3500" speed="800"}\n:::card {title="Card" icon="dashboard"}\nLas directivas se anidan dentro.\n:::\n---\n> **Admonici\xF3n** como diapositiva\n---\n| P\xE1gina | Tema |\n| --- | --- |\n| 1 | Slide |\n| 2 | Loop |\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `interval` | ms | Tiempo por diapositiva (default `3000`) |\n| `speed` | ms | Duraci\xF3n de la transici\xF3n (default `500`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Notas\n\n-
|
|
12954
|
+
"md": '# Slide\n\nLa directiva `:::slide` convierte su contenido en un **slider autom\xE1tico** (diapositivas con fade).\n\n## Sintaxis\n\nLas secciones se separan con `---`:\n\n```md\n:::slide {interval="2500"}\n## Diapositiva 1\n\nBienvenido a la **gu\xEDa interactiva**.\n\n---\n\n## Diapositiva 2\n\nCada `---` separa una diapositiva nueva.\n\n---\n\n## Diapositiva 3\n\nY el motor se encarga del resto.\n:::\n```\n\n:::slide {interval="2500"}\n## Diapositiva 1\n\nBienvenido a la **gu\xEDa interactiva**.\n\n---\n\n## Diapositiva 2\n\nCada `---` separa una diapositiva nueva.\n\n---\n\n## Diapositiva 3\n\nY el motor se encarga del resto.\n:::\n\n## Con contenido variado\n\n```md\n:::slide {interval="3500" speed="800"}\n:::card {title="Card" icon="dashboard"}\nLas directivas se anidan dentro.\n:::\n---\n> **Admonici\xF3n** como diapositiva\n---\n| P\xE1gina | Tema |\n| --- | --- |\n| 1 | Slide |\n| 2 | Loop |\n:::\n```\n\n:::slide {interval="3500" speed="800"}\n:::card {title="Card" icon="dashboard"}\nLas directivas se anidan dentro.\n:::\n---\n> **Admonici\xF3n** como diapositiva\n---\n| P\xE1gina | Tema |\n| --- | --- |\n| 1 | Slide |\n| 2 | Loop |\n:::\n\n## Props\n\n| Prop | Tipo | Descripci\xF3n |\n| --- | --- | --- |\n| `interval` | ms | Tiempo por diapositiva (default `3000`) |\n| `speed` | ms | Duraci\xF3n de la transici\xF3n (default `500`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline |\n\n## Notas\n\n- Al llegar a la \\u00faltima diapositiva, vuelve a la primera autom\\u00e1ticamente (loop).\n- El contenido de cada diapositiva admite markdown completo y directivas anidadas.\n- La altura del contenedor se adapta autom\\u00e1ticamente al contenido m\\u00e1s alto.'
|
|
12963
12955
|
},
|
|
12964
12956
|
{
|
|
12965
12957
|
"id": "html-blocks",
|
|
@@ -12982,6 +12974,7 @@ var Guide = ({
|
|
|
12982
12974
|
const [query, setQuery] = (0, import_react4.useState)("");
|
|
12983
12975
|
const [selectedId, setSelectedId] = (0, import_react4.useState)(null);
|
|
12984
12976
|
const [collapsed, setCollapsed] = (0, import_react4.useState)({});
|
|
12977
|
+
const [navOpen, setNavOpen] = (0, import_react4.useState)(false);
|
|
12985
12978
|
const contentRef = (0, import_react4.useRef)(null);
|
|
12986
12979
|
const groups = (0, import_react4.useMemo)(() => {
|
|
12987
12980
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -13009,6 +13002,7 @@ var Guide = ({
|
|
|
13009
13002
|
(0, import_react4.useEffect)(() => {
|
|
13010
13003
|
if (!open) return;
|
|
13011
13004
|
setQuery("");
|
|
13005
|
+
setNavOpen(false);
|
|
13012
13006
|
if (!selectedId) {
|
|
13013
13007
|
const initial = guideData.find((e) => e.id === initialDirective) ?? guideData.find((e) => e.id === "introduccion") ?? guideData[0];
|
|
13014
13008
|
setSelectedId(initial?.id ?? null);
|
|
@@ -13041,6 +13035,15 @@ var Guide = ({
|
|
|
13041
13035
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "nr-guide__overlay", onClick: onClose }),
|
|
13042
13036
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "nr-guide__panel", children: [
|
|
13043
13037
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "nr-guide__head", children: [
|
|
13038
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
13039
|
+
"button",
|
|
13040
|
+
{
|
|
13041
|
+
className: "nr-guide__nav-toggle",
|
|
13042
|
+
onClick: () => setNavOpen(true),
|
|
13043
|
+
"aria-label": "Abrir navegaci\xF3n",
|
|
13044
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "material-icons-round", children: "menu" })
|
|
13045
|
+
}
|
|
13046
|
+
),
|
|
13044
13047
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "material-icons-round", children: "menu_book" }),
|
|
13045
13048
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { children: "Gu\xEDa de sintaxis" }),
|
|
13046
13049
|
search && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -13064,6 +13067,43 @@ var Guide = ({
|
|
|
13064
13067
|
)
|
|
13065
13068
|
] }),
|
|
13066
13069
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "nr-guide__body", children: [
|
|
13070
|
+
navOpen && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
13071
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "nr-guide__nav-overlay", onClick: () => setNavOpen(false) }),
|
|
13072
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "nr-guide__nav-drawer nr-guide__nav-drawer--open", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("nav", { children: [
|
|
13073
|
+
filtered.map(([cat, entries]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "nr-guide__cat", children: [
|
|
13074
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
13075
|
+
"button",
|
|
13076
|
+
{
|
|
13077
|
+
className: "nr-guide__cat-head",
|
|
13078
|
+
onClick: () => toggleCategory(cat),
|
|
13079
|
+
children: [
|
|
13080
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "material-icons-round nr-guide__cat-chevron", children: collapsed[cat] ? "chevron_right" : "expand_more" }),
|
|
13081
|
+
cat
|
|
13082
|
+
]
|
|
13083
|
+
}
|
|
13084
|
+
),
|
|
13085
|
+
!collapsed[cat] && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "nr-guide__items", children: entries.map((e) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
13086
|
+
"button",
|
|
13087
|
+
{
|
|
13088
|
+
className: `nr-guide__item${selectedId === e.id ? " nr-guide__item--active" : ""}`,
|
|
13089
|
+
onClick: () => {
|
|
13090
|
+
setSelectedId(e.id);
|
|
13091
|
+
setNavOpen(false);
|
|
13092
|
+
},
|
|
13093
|
+
children: [
|
|
13094
|
+
e.icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "material-icons-round nr-guide__item-icon", children: e.icon }),
|
|
13095
|
+
e.title
|
|
13096
|
+
]
|
|
13097
|
+
}
|
|
13098
|
+
) }, e.id)) })
|
|
13099
|
+
] }, cat)),
|
|
13100
|
+
filtered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "nr-guide__empty", children: [
|
|
13101
|
+
"Sin resultados para \xAB",
|
|
13102
|
+
query,
|
|
13103
|
+
"\xBB."
|
|
13104
|
+
] })
|
|
13105
|
+
] }) })
|
|
13106
|
+
] }),
|
|
13067
13107
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("nav", { className: "nr-guide__nav", children: [
|
|
13068
13108
|
filtered.map(([cat, entries]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "nr-guide__cat", children: [
|
|
13069
13109
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|