@noirmd/previewer 2.1.4 → 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 +153 -161
- package/dist/NReditor.cjs.map +1 -1
- package/dist/NReditor.js +153 -161
- package/dist/NReditor.js.map +1 -1
- package/dist/button.css +6 -0
- package/dist/card.css +5 -5
- 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/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 +153 -161
- 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 +153 -161
- 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/package.json +1 -1
package/dist/react.d.cts
CHANGED
package/dist/react.d.ts
CHANGED
package/dist/react.js
CHANGED
|
@@ -1653,6 +1653,22 @@ function parseHtmlAttrs(attrsString) {
|
|
|
1653
1653
|
}
|
|
1654
1654
|
|
|
1655
1655
|
// core/parser.ts
|
|
1656
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
1657
|
+
"area",
|
|
1658
|
+
"base",
|
|
1659
|
+
"br",
|
|
1660
|
+
"col",
|
|
1661
|
+
"embed",
|
|
1662
|
+
"hr",
|
|
1663
|
+
"img",
|
|
1664
|
+
"input",
|
|
1665
|
+
"link",
|
|
1666
|
+
"meta",
|
|
1667
|
+
"param",
|
|
1668
|
+
"source",
|
|
1669
|
+
"track",
|
|
1670
|
+
"wbr"
|
|
1671
|
+
]);
|
|
1656
1672
|
function parseMarkdown(markdown2) {
|
|
1657
1673
|
if (!markdown2) return [];
|
|
1658
1674
|
const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
|
|
@@ -1666,8 +1682,19 @@ function parseMarkdown(markdown2) {
|
|
|
1666
1682
|
if (match = trimmed.match(/^(#{1,6})\s+(.+)$/)) {
|
|
1667
1683
|
const level = match[1].length;
|
|
1668
1684
|
const rawText = match[2];
|
|
1669
|
-
const { text:
|
|
1670
|
-
|
|
1685
|
+
const { text: rawParsedText, classes: classes2, id: customId } = extractAttributes(rawText);
|
|
1686
|
+
let text2 = rawParsedText;
|
|
1687
|
+
let align;
|
|
1688
|
+
const alignCenter = text2.match(/^->\s*(.+?)\s*<-\s*$/);
|
|
1689
|
+
const alignRight = text2.match(/^->\s*(.+?)\s*->\s*$/);
|
|
1690
|
+
if (alignCenter) {
|
|
1691
|
+
text2 = alignCenter[1];
|
|
1692
|
+
align = "center";
|
|
1693
|
+
} else if (alignRight) {
|
|
1694
|
+
text2 = alignRight[1];
|
|
1695
|
+
align = "right";
|
|
1696
|
+
}
|
|
1697
|
+
const baseId = customId || generateId(text2);
|
|
1671
1698
|
let id2 = baseId;
|
|
1672
1699
|
let n = 1;
|
|
1673
1700
|
while (usedIds.has(id2)) {
|
|
@@ -1675,7 +1702,7 @@ function parseMarkdown(markdown2) {
|
|
|
1675
1702
|
id2 = `${baseId}-${n}`;
|
|
1676
1703
|
}
|
|
1677
1704
|
usedIds.add(id2);
|
|
1678
|
-
result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0 });
|
|
1705
|
+
result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0, align });
|
|
1679
1706
|
i++;
|
|
1680
1707
|
continue;
|
|
1681
1708
|
}
|
|
@@ -1851,29 +1878,13 @@ function parseMarkdown(markdown2) {
|
|
|
1851
1878
|
let tagStartMatch = trimmed.match(/^<([a-zA-Z][\w-]*)/);
|
|
1852
1879
|
if (tagStartMatch) {
|
|
1853
1880
|
const tagName = tagStartMatch[1].toLowerCase();
|
|
1854
|
-
const voidElements = /* @__PURE__ */ new Set([
|
|
1855
|
-
"area",
|
|
1856
|
-
"base",
|
|
1857
|
-
"br",
|
|
1858
|
-
"col",
|
|
1859
|
-
"embed",
|
|
1860
|
-
"hr",
|
|
1861
|
-
"img",
|
|
1862
|
-
"input",
|
|
1863
|
-
"link",
|
|
1864
|
-
"meta",
|
|
1865
|
-
"param",
|
|
1866
|
-
"source",
|
|
1867
|
-
"track",
|
|
1868
|
-
"wbr"
|
|
1869
|
-
]);
|
|
1870
1881
|
const remainingText = lines.slice(i).join("\n");
|
|
1871
1882
|
const openTagRegex = new RegExp(`^\\s*<${tagName}\\b([^>]*?)>`, "i");
|
|
1872
1883
|
const openTagMatch = remainingText.match(openTagRegex);
|
|
1873
1884
|
if (openTagMatch) {
|
|
1874
1885
|
const fullOpenTag = openTagMatch[0];
|
|
1875
1886
|
const attrs = openTagMatch[1].replace(/\s+/g, " ").trim();
|
|
1876
|
-
const isSelfClosing = fullOpenTag.endsWith("/>") ||
|
|
1887
|
+
const isSelfClosing = fullOpenTag.endsWith("/>") || VOID_ELEMENTS.has(tagName);
|
|
1877
1888
|
if (isSelfClosing) {
|
|
1878
1889
|
const blockText = remainingText.substring(0, openTagMatch.index + fullOpenTag.length);
|
|
1879
1890
|
const consumedLines = blockText.split("\n").length;
|
|
@@ -11267,11 +11278,77 @@ function parseInlinePart(part) {
|
|
|
11267
11278
|
return document.createTextNode(part);
|
|
11268
11279
|
}
|
|
11269
11280
|
|
|
11281
|
+
// vanilla/utils.ts
|
|
11282
|
+
var THEME_TOKENS = /* @__PURE__ */ new Set([
|
|
11283
|
+
"primary",
|
|
11284
|
+
"secondary",
|
|
11285
|
+
"accent",
|
|
11286
|
+
"neutral",
|
|
11287
|
+
"info",
|
|
11288
|
+
"success",
|
|
11289
|
+
"warning",
|
|
11290
|
+
"error"
|
|
11291
|
+
]);
|
|
11292
|
+
function isThemeToken(color) {
|
|
11293
|
+
return !!color && THEME_TOKENS.has(color);
|
|
11294
|
+
}
|
|
11295
|
+
function isArbitraryColor(value) {
|
|
11296
|
+
if (THEME_TOKENS.has(value)) return false;
|
|
11297
|
+
if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
|
|
11298
|
+
if (/^[a-zA-Z]+$/.test(value)) return true;
|
|
11299
|
+
return false;
|
|
11300
|
+
}
|
|
11301
|
+
function applyBaseProps(el, props) {
|
|
11302
|
+
if (props.class) {
|
|
11303
|
+
el.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
11304
|
+
}
|
|
11305
|
+
if (props.style) {
|
|
11306
|
+
const styles = parseCssString(props.style);
|
|
11307
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
11308
|
+
el.style.setProperty(key, String(value));
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
}
|
|
11312
|
+
function applyFloatStyle(el, float, width) {
|
|
11313
|
+
if (!float) return;
|
|
11314
|
+
if (float === "left" || float === "right") {
|
|
11315
|
+
el.style.float = float;
|
|
11316
|
+
if (!width) el.style.maxWidth = "50%";
|
|
11317
|
+
el.style.marginInlineStart = float === "right" ? "1rem" : "";
|
|
11318
|
+
el.style.marginInlineEnd = float === "left" ? "1rem" : "";
|
|
11319
|
+
} else if (float === "center") {
|
|
11320
|
+
el.style.marginInline = "auto";
|
|
11321
|
+
}
|
|
11322
|
+
}
|
|
11323
|
+
function applyColor(el, color, classSuffix) {
|
|
11324
|
+
if (!color) return "";
|
|
11325
|
+
if (isThemeToken(color)) {
|
|
11326
|
+
return ` ${classSuffix}--${color}`;
|
|
11327
|
+
}
|
|
11328
|
+
if (isArbitraryColor(color)) {
|
|
11329
|
+
el.style.background = color;
|
|
11330
|
+
el.style.color = "white";
|
|
11331
|
+
}
|
|
11332
|
+
return "";
|
|
11333
|
+
}
|
|
11334
|
+
function openModal(dialog) {
|
|
11335
|
+
if (!dialog.open) {
|
|
11336
|
+
document.body.appendChild(dialog);
|
|
11337
|
+
dialog.showModal();
|
|
11338
|
+
dialog.addEventListener("close", () => dialog.remove(), { once: true });
|
|
11339
|
+
}
|
|
11340
|
+
}
|
|
11341
|
+
var IMG_RE = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11342
|
+
function parseIntProp(value, defaultValue) {
|
|
11343
|
+
if (!value) return defaultValue;
|
|
11344
|
+
const n = parseInt(value, 10);
|
|
11345
|
+
return Number.isNaN(n) ? defaultValue : n;
|
|
11346
|
+
}
|
|
11347
|
+
|
|
11270
11348
|
// vanilla/directives/admonition.ts
|
|
11271
11349
|
var admonitionDirective = ({ directiveType, props, renderSlot }) => {
|
|
11272
11350
|
const el = createAdmonition(directiveType, props.title, props.icon);
|
|
11273
|
-
|
|
11274
|
-
if (props.style) el.setAttribute("style", props.style);
|
|
11351
|
+
applyBaseProps(el, props);
|
|
11275
11352
|
const body = el.querySelector(".nr-admonition__body");
|
|
11276
11353
|
if (body) {
|
|
11277
11354
|
body.appendChild(renderSlot("default"));
|
|
@@ -11287,8 +11364,7 @@ var detailsDirective = ({ props, renderSlot }) => {
|
|
|
11287
11364
|
props.icon,
|
|
11288
11365
|
props.defaultOpen === "true"
|
|
11289
11366
|
);
|
|
11290
|
-
|
|
11291
|
-
if (props.style) el.setAttribute("style", props.style);
|
|
11367
|
+
applyBaseProps(el, props);
|
|
11292
11368
|
const body = el.querySelector(".nr-details__body");
|
|
11293
11369
|
if (body) {
|
|
11294
11370
|
body.appendChild(renderSlot("default"));
|
|
@@ -11301,12 +11377,12 @@ var details_default = detailsDirective;
|
|
|
11301
11377
|
var modalDirective = ({ props, renderSlot }) => {
|
|
11302
11378
|
const label = props.label || props.title || "Open";
|
|
11303
11379
|
const modalTitle = props.title || "Modal";
|
|
11304
|
-
const
|
|
11380
|
+
const align = props.align || "left";
|
|
11305
11381
|
const wrapper = document.createElement("div");
|
|
11306
|
-
wrapper.className = "nr-modal-trigger"
|
|
11382
|
+
wrapper.className = `nr-modal-trigger${align === "center" ? " nr-modal-trigger--center" : align === "right" ? " nr-modal-trigger--right" : ""}`;
|
|
11307
11383
|
const btn = document.createElement("button");
|
|
11308
11384
|
btn.className = `nr-button nr-button--default`;
|
|
11309
|
-
|
|
11385
|
+
applyBaseProps(btn, props);
|
|
11310
11386
|
const icon = props.icon || "open_in_new";
|
|
11311
11387
|
if (icon) btn.appendChild(createIcon(icon));
|
|
11312
11388
|
btn.appendChild(document.createTextNode(label));
|
|
@@ -11318,15 +11394,7 @@ var modalDirective = ({ props, renderSlot }) => {
|
|
|
11318
11394
|
prose.appendChild(renderSlot("default"));
|
|
11319
11395
|
body.appendChild(prose);
|
|
11320
11396
|
}
|
|
11321
|
-
btn.addEventListener("click", () =>
|
|
11322
|
-
if (!dialog.open) {
|
|
11323
|
-
document.body.appendChild(dialog);
|
|
11324
|
-
dialog.showModal();
|
|
11325
|
-
dialog.addEventListener("close", () => {
|
|
11326
|
-
dialog.remove();
|
|
11327
|
-
}, { once: true });
|
|
11328
|
-
}
|
|
11329
|
-
});
|
|
11397
|
+
btn.addEventListener("click", () => openModal(dialog));
|
|
11330
11398
|
wrapper.appendChild(btn);
|
|
11331
11399
|
wrapper.appendChild(dialog);
|
|
11332
11400
|
return wrapper;
|
|
@@ -11336,19 +11404,20 @@ var modal_default = modalDirective;
|
|
|
11336
11404
|
// vanilla/directives/button.ts
|
|
11337
11405
|
var buttonDirective = ({ props, renderSlot }) => {
|
|
11338
11406
|
const url = props.url || props.href || "#";
|
|
11339
|
-
const label = props.label;
|
|
11407
|
+
const label = props.label || props.title;
|
|
11340
11408
|
const icon = props.icon || "near_me";
|
|
11341
11409
|
const target = props.target || "_blank";
|
|
11342
11410
|
const customClass = props.class || "";
|
|
11411
|
+
const align = props.align || "left";
|
|
11343
11412
|
const wrapper = document.createElement("div");
|
|
11344
|
-
wrapper.className = "nr-button-wrap"
|
|
11413
|
+
wrapper.className = `nr-button-wrap${align === "center" ? " nr-button-wrap--center" : align === "right" ? " nr-button-wrap--right" : ""}`;
|
|
11345
11414
|
if (label) {
|
|
11346
11415
|
const a = document.createElement("a");
|
|
11347
11416
|
a.href = url;
|
|
11348
11417
|
a.target = target;
|
|
11349
11418
|
a.rel = "noopener noreferrer";
|
|
11350
11419
|
a.className = "nr-button nr-button--default";
|
|
11351
|
-
|
|
11420
|
+
applyBaseProps(a, props);
|
|
11352
11421
|
a.appendChild(createIcon(icon));
|
|
11353
11422
|
a.appendChild(document.createTextNode(label));
|
|
11354
11423
|
wrapper.appendChild(a);
|
|
@@ -11359,7 +11428,7 @@ var buttonDirective = ({ props, renderSlot }) => {
|
|
|
11359
11428
|
if (links.length > 0) {
|
|
11360
11429
|
links.forEach((link) => {
|
|
11361
11430
|
link.classList.add("nr-button", "nr-button--default");
|
|
11362
|
-
|
|
11431
|
+
applyBaseProps(link, props);
|
|
11363
11432
|
});
|
|
11364
11433
|
wrapper.appendChild(slotContent);
|
|
11365
11434
|
} else {
|
|
@@ -11368,7 +11437,7 @@ var buttonDirective = ({ props, renderSlot }) => {
|
|
|
11368
11437
|
a.target = target;
|
|
11369
11438
|
a.rel = "noopener noreferrer";
|
|
11370
11439
|
a.className = "nr-button nr-button--default";
|
|
11371
|
-
|
|
11440
|
+
applyBaseProps(a, props);
|
|
11372
11441
|
a.appendChild(createIcon(icon));
|
|
11373
11442
|
a.appendChild(slotContent);
|
|
11374
11443
|
wrapper.appendChild(a);
|
|
@@ -11391,12 +11460,9 @@ var cardDirective = ({
|
|
|
11391
11460
|
const { isSingleCard } = options || {};
|
|
11392
11461
|
const isModal = directiveType === "card-m";
|
|
11393
11462
|
const isLink = directiveType === "card-b";
|
|
11394
|
-
const inlineStyles = props.style ? parseCssString(props.style) : {};
|
|
11395
11463
|
const card = document.createElement("div");
|
|
11396
11464
|
card.className = `nr-card${isModal || isLink ? " nr-card--interactive" : ""} ${customClass}`.trim();
|
|
11397
|
-
|
|
11398
|
-
card.style.setProperty(key, String(value));
|
|
11399
|
-
}
|
|
11465
|
+
applyBaseProps(card, props);
|
|
11400
11466
|
if (image) {
|
|
11401
11467
|
const imgWrap = document.createElement("div");
|
|
11402
11468
|
imgWrap.className = `nr-card__image${isSingleCard ? " nr-card__image--tall" : ""}`;
|
|
@@ -11475,13 +11541,7 @@ var cardDirective = ({
|
|
|
11475
11541
|
prose.appendChild(renderSlot("content") || renderSlot("default"));
|
|
11476
11542
|
modalBody.appendChild(prose);
|
|
11477
11543
|
}
|
|
11478
|
-
card.addEventListener("click", () =>
|
|
11479
|
-
if (!dialog.open) {
|
|
11480
|
-
document.body.appendChild(dialog);
|
|
11481
|
-
dialog.showModal();
|
|
11482
|
-
dialog.addEventListener("close", () => dialog.remove(), { once: true });
|
|
11483
|
-
}
|
|
11484
|
-
});
|
|
11544
|
+
card.addEventListener("click", () => openModal(dialog));
|
|
11485
11545
|
const frag = document.createDocumentFragment();
|
|
11486
11546
|
frag.appendChild(card);
|
|
11487
11547
|
frag.appendChild(dialog);
|
|
@@ -11529,8 +11589,8 @@ var slideDirective = ({
|
|
|
11529
11589
|
if (lines.length === 0) {
|
|
11530
11590
|
return document.createDocumentFragment();
|
|
11531
11591
|
}
|
|
11532
|
-
const interval =
|
|
11533
|
-
const speed =
|
|
11592
|
+
const interval = parseIntProp(props.interval, 3e3);
|
|
11593
|
+
const speed = parseIntProp(props.speed, 500);
|
|
11534
11594
|
const rawClass = props.class || "";
|
|
11535
11595
|
const inlineStyle = props.style ? parseCssString(props.style) : {};
|
|
11536
11596
|
const scopeClass = `sld-${++slideCounter}`;
|
|
@@ -11581,10 +11641,11 @@ var slideDirective = ({
|
|
|
11581
11641
|
}
|
|
11582
11642
|
});
|
|
11583
11643
|
if (lines.length > 1) {
|
|
11584
|
-
setInterval(() => {
|
|
11644
|
+
const id = setInterval(() => {
|
|
11585
11645
|
current = (current + 1) % lines.length;
|
|
11586
11646
|
track.style.transform = `translateY(${-current * maxH}px)`;
|
|
11587
11647
|
}, interval);
|
|
11648
|
+
container.dataset.nrIntervalId = String(id);
|
|
11588
11649
|
}
|
|
11589
11650
|
return container;
|
|
11590
11651
|
};
|
|
@@ -11594,8 +11655,7 @@ var slide_default = slideDirective;
|
|
|
11594
11655
|
var keysDirective = ({ props, slots }) => {
|
|
11595
11656
|
const wrap = document.createElement("div");
|
|
11596
11657
|
wrap.className = "nr-keys";
|
|
11597
|
-
|
|
11598
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11658
|
+
applyBaseProps(wrap, props);
|
|
11599
11659
|
const sizeClass = props.size ? ` nr-kbd--${props.size}` : "";
|
|
11600
11660
|
const parts = (slots.default || "").split("+").map((p) => p.trim()).filter(Boolean);
|
|
11601
11661
|
parts.forEach((part, i) => {
|
|
@@ -11619,8 +11679,7 @@ var accordionCounter = 0;
|
|
|
11619
11679
|
var accordionItemDirective = ({ props, renderSlot }) => {
|
|
11620
11680
|
const item = document.createElement("div");
|
|
11621
11681
|
item.className = "nr-accordion__item";
|
|
11622
|
-
|
|
11623
|
-
if (props.style) item.setAttribute("style", props.style);
|
|
11682
|
+
applyBaseProps(item, props);
|
|
11624
11683
|
const input = document.createElement("input");
|
|
11625
11684
|
input.type = "radio";
|
|
11626
11685
|
input.className = "nr-accordion__input";
|
|
@@ -11639,8 +11698,7 @@ var accordionItemDirective = ({ props, renderSlot }) => {
|
|
|
11639
11698
|
var accordionDirective = ({ props, renderSlot }) => {
|
|
11640
11699
|
const wrap = document.createElement("div");
|
|
11641
11700
|
wrap.className = "nr-accordion";
|
|
11642
|
-
|
|
11643
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11701
|
+
applyBaseProps(wrap, props);
|
|
11644
11702
|
wrap.appendChild(renderSlot("default"));
|
|
11645
11703
|
const mode = props.mode === "checkbox" ? "checkbox" : "radio";
|
|
11646
11704
|
const group = `nr-acc-${++accordionCounter}`;
|
|
@@ -11653,7 +11711,6 @@ var accordionDirective = ({ props, renderSlot }) => {
|
|
|
11653
11711
|
var accordion_default = accordionDirective;
|
|
11654
11712
|
|
|
11655
11713
|
// vanilla/directives/carousel.ts
|
|
11656
|
-
var IMG_RE = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11657
11714
|
var carouselDirective = ({ props, slots }) => {
|
|
11658
11715
|
const images = [];
|
|
11659
11716
|
const raw = slots.default || "";
|
|
@@ -11669,19 +11726,9 @@ var carouselDirective = ({ props, slots }) => {
|
|
|
11669
11726
|
wrap.className = "nr-carousel";
|
|
11670
11727
|
wrap.tabIndex = 0;
|
|
11671
11728
|
wrap.setAttribute("aria-label", "Image carousel");
|
|
11672
|
-
|
|
11673
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11729
|
+
applyBaseProps(wrap, props);
|
|
11674
11730
|
if (props.width) wrap.style.width = props.width;
|
|
11675
|
-
|
|
11676
|
-
if (props.float === "left" || props.float === "right") {
|
|
11677
|
-
wrap.style.float = props.float;
|
|
11678
|
-
if (!props.width) wrap.style.maxWidth = "50%";
|
|
11679
|
-
wrap.style.marginInlineStart = props.float === "right" ? "1rem" : "";
|
|
11680
|
-
wrap.style.marginInlineEnd = props.float === "left" ? "1rem" : "";
|
|
11681
|
-
} else if (props.float === "center") {
|
|
11682
|
-
wrap.style.marginInline = "auto";
|
|
11683
|
-
}
|
|
11684
|
-
}
|
|
11731
|
+
applyFloatStyle(wrap, props.float, props.width);
|
|
11685
11732
|
const viewport = document.createElement("div");
|
|
11686
11733
|
viewport.className = "nr-carousel__viewport";
|
|
11687
11734
|
if (props.height) viewport.style.height = props.height;
|
|
@@ -11751,11 +11798,10 @@ var DEFAULT_LABELS = ["days", "hours", "min", "sec"];
|
|
|
11751
11798
|
var countdownDirective = ({ props }) => {
|
|
11752
11799
|
const wrap = document.createElement("div");
|
|
11753
11800
|
wrap.className = "nr-countdown";
|
|
11754
|
-
|
|
11755
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
11801
|
+
applyBaseProps(wrap, props);
|
|
11756
11802
|
const labelParts = (props.labels || "").split("|").map((s) => s.trim());
|
|
11757
11803
|
const labels = DEFAULT_LABELS.map((label, i) => labelParts[i] || label);
|
|
11758
|
-
const digits =
|
|
11804
|
+
const digits = parseIntProp(props.digits, 2);
|
|
11759
11805
|
const targetTime = props.target ? new Date(props.target).getTime() : NaN;
|
|
11760
11806
|
const hasTarget = !Number.isNaN(targetTime);
|
|
11761
11807
|
const blocks = [];
|
|
@@ -11802,13 +11848,15 @@ var countdownDirective = ({ props }) => {
|
|
|
11802
11848
|
blocks.push({ value });
|
|
11803
11849
|
});
|
|
11804
11850
|
render();
|
|
11805
|
-
if (hasTarget)
|
|
11851
|
+
if (hasTarget) {
|
|
11852
|
+
const id = setInterval(render, 1e3);
|
|
11853
|
+
wrap.dataset.nrIntervalId = String(id);
|
|
11854
|
+
}
|
|
11806
11855
|
return wrap;
|
|
11807
11856
|
};
|
|
11808
11857
|
var countdown_default = countdownDirective;
|
|
11809
11858
|
|
|
11810
11859
|
// vanilla/directives/diff.ts
|
|
11811
|
-
var IMG_RE2 = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11812
11860
|
var diffDirective = ({ props, slots }) => {
|
|
11813
11861
|
let before = (props.before || "").split("#")[0].trim();
|
|
11814
11862
|
let after = (props.after || "").split("#")[0].trim();
|
|
@@ -11816,8 +11864,8 @@ var diffDirective = ({ props, slots }) => {
|
|
|
11816
11864
|
const urls = [];
|
|
11817
11865
|
const raw = slots.default || "";
|
|
11818
11866
|
let m;
|
|
11819
|
-
|
|
11820
|
-
while ((m =
|
|
11867
|
+
IMG_RE.lastIndex = 0;
|
|
11868
|
+
while ((m = IMG_RE.exec(raw)) !== null) {
|
|
11821
11869
|
urls.push(m[2].split("#")[0].trim());
|
|
11822
11870
|
}
|
|
11823
11871
|
if (!before && urls.length > 0) before = urls[0];
|
|
@@ -11830,21 +11878,11 @@ var diffDirective = ({ props, slots }) => {
|
|
|
11830
11878
|
figure.className = "nr-diff";
|
|
11831
11879
|
figure.tabIndex = 0;
|
|
11832
11880
|
figure.setAttribute("aria-label", "Image comparison slider");
|
|
11833
|
-
|
|
11834
|
-
if (props.style) figure.setAttribute("style", props.style);
|
|
11881
|
+
applyBaseProps(figure, props);
|
|
11835
11882
|
if (props.aspect) figure.style.aspectRatio = props.aspect;
|
|
11836
11883
|
if (props.height) figure.style.height = props.height;
|
|
11837
11884
|
if (props.width) figure.style.width = props.width;
|
|
11838
|
-
|
|
11839
|
-
if (props.float === "left" || props.float === "right") {
|
|
11840
|
-
figure.style.float = props.float;
|
|
11841
|
-
if (!props.width) figure.style.maxWidth = "50%";
|
|
11842
|
-
figure.style.marginInlineStart = props.float === "right" ? "1rem" : "";
|
|
11843
|
-
figure.style.marginInlineEnd = props.float === "left" ? "1rem" : "";
|
|
11844
|
-
} else if (props.float === "center") {
|
|
11845
|
-
figure.style.marginInline = "auto";
|
|
11846
|
-
}
|
|
11847
|
-
}
|
|
11885
|
+
applyFloatStyle(figure, props.float, props.width);
|
|
11848
11886
|
const beforeItem = document.createElement("div");
|
|
11849
11887
|
beforeItem.className = "nr-diff__item nr-diff__item--before";
|
|
11850
11888
|
beforeItem.setAttribute("role", "img");
|
|
@@ -11907,8 +11945,7 @@ var diff_default = diffDirective;
|
|
|
11907
11945
|
var hover3dDirective = ({ props, renderSlot }) => {
|
|
11908
11946
|
const container = document.createElement("div");
|
|
11909
11947
|
container.className = "nr-hover-3d";
|
|
11910
|
-
|
|
11911
|
-
if (props.style) container.setAttribute("style", props.style);
|
|
11948
|
+
applyBaseProps(container, props);
|
|
11912
11949
|
const stage = document.createElement("div");
|
|
11913
11950
|
stage.className = "nr-hover-3d__stage";
|
|
11914
11951
|
stage.appendChild(renderSlot("default"));
|
|
@@ -11921,14 +11958,13 @@ var hover3dDirective = ({ props, renderSlot }) => {
|
|
|
11921
11958
|
var hover3d_default = hover3dDirective;
|
|
11922
11959
|
|
|
11923
11960
|
// vanilla/directives/hovergallery.ts
|
|
11924
|
-
var IMG_RE3 = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
11925
11961
|
var MAX_IMAGES = 10;
|
|
11926
11962
|
var hovergalleryDirective = ({ props, slots }) => {
|
|
11927
11963
|
const images = [];
|
|
11928
11964
|
const raw = slots.default || "";
|
|
11929
11965
|
let m;
|
|
11930
|
-
|
|
11931
|
-
while ((m =
|
|
11966
|
+
IMG_RE.lastIndex = 0;
|
|
11967
|
+
while ((m = IMG_RE.exec(raw)) !== null) {
|
|
11932
11968
|
images.push({ src: m[2].split("#")[0].trim(), alt: m[1].trim() || "gallery image" });
|
|
11933
11969
|
}
|
|
11934
11970
|
if (images.length === 0) {
|
|
@@ -11937,9 +11973,8 @@ var hovergalleryDirective = ({ props, slots }) => {
|
|
|
11937
11973
|
const count = Math.min(images.length, MAX_IMAGES);
|
|
11938
11974
|
const figure = document.createElement("figure");
|
|
11939
11975
|
figure.className = "nr-hover-gallery";
|
|
11976
|
+
applyBaseProps(figure, props);
|
|
11940
11977
|
if (props.aspect) figure.style.aspectRatio = props.aspect;
|
|
11941
|
-
if (props.class) figure.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
11942
|
-
if (props.style) figure.setAttribute("style", (figure.getAttribute("style") || "") + ";" + props.style);
|
|
11943
11978
|
const imgEls = [];
|
|
11944
11979
|
for (let i = 0; i < count; i++) {
|
|
11945
11980
|
const el = document.createElement("img");
|
|
@@ -11989,28 +12024,11 @@ var hovergalleryDirective = ({ props, slots }) => {
|
|
|
11989
12024
|
var hovergallery_default = hovergalleryDirective;
|
|
11990
12025
|
|
|
11991
12026
|
// vanilla/directives/chat.ts
|
|
11992
|
-
var CHAT_THEME_TOKENS = /* @__PURE__ */ new Set([
|
|
11993
|
-
"primary",
|
|
11994
|
-
"secondary",
|
|
11995
|
-
"accent",
|
|
11996
|
-
"neutral",
|
|
11997
|
-
"info",
|
|
11998
|
-
"success",
|
|
11999
|
-
"warning",
|
|
12000
|
-
"error"
|
|
12001
|
-
]);
|
|
12002
|
-
function isArbitraryColor(value) {
|
|
12003
|
-
if (CHAT_THEME_TOKENS.has(value)) return false;
|
|
12004
|
-
if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
|
|
12005
|
-
if (/^[a-zA-Z]+$/.test(value)) return true;
|
|
12006
|
-
return false;
|
|
12007
|
-
}
|
|
12008
12027
|
var chatItemDirective = ({ props, renderSlot }) => {
|
|
12009
12028
|
const side = props.side === "end" ? "end" : "start";
|
|
12010
12029
|
const wrap = document.createElement("div");
|
|
12011
12030
|
wrap.className = `nr-chat nr-chat--${side}`;
|
|
12012
|
-
|
|
12013
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
12031
|
+
applyBaseProps(wrap, props);
|
|
12014
12032
|
const header = document.createElement("div");
|
|
12015
12033
|
header.className = "nr-chat__header";
|
|
12016
12034
|
if (props.name) {
|
|
@@ -12035,14 +12053,8 @@ var chatItemDirective = ({ props, renderSlot }) => {
|
|
|
12035
12053
|
avatar.appendChild(img);
|
|
12036
12054
|
wrap.appendChild(avatar);
|
|
12037
12055
|
}
|
|
12038
|
-
const isThemeToken = CHAT_THEME_TOKENS.has(props.color || "");
|
|
12039
|
-
const colorClass = isThemeToken ? ` nr-chat__bubble--${props.color}` : "";
|
|
12040
12056
|
const bubble = document.createElement("div");
|
|
12041
|
-
bubble.className = `nr-chat__bubble${
|
|
12042
|
-
if (props.color && isArbitraryColor(props.color) && !isThemeToken) {
|
|
12043
|
-
bubble.style.background = props.color;
|
|
12044
|
-
bubble.style.color = "white";
|
|
12045
|
-
}
|
|
12057
|
+
bubble.className = `nr-chat__bubble${applyColor(bubble, props.color, "nr-chat__bubble")}`;
|
|
12046
12058
|
bubble.appendChild(renderSlot("default"));
|
|
12047
12059
|
wrap.appendChild(bubble);
|
|
12048
12060
|
if (props.footer) {
|
|
@@ -12056,8 +12068,7 @@ var chatItemDirective = ({ props, renderSlot }) => {
|
|
|
12056
12068
|
var chatDirective = ({ props, renderSlot }) => {
|
|
12057
12069
|
const wrap = document.createElement("div");
|
|
12058
12070
|
wrap.className = "nr-chat";
|
|
12059
|
-
|
|
12060
|
-
if (props.style) wrap.setAttribute("style", props.style);
|
|
12071
|
+
applyBaseProps(wrap, props);
|
|
12061
12072
|
wrap.appendChild(renderSlot("default"));
|
|
12062
12073
|
return wrap;
|
|
12063
12074
|
};
|
|
@@ -12093,8 +12104,7 @@ function bindEventProp(el, eventProp) {
|
|
|
12093
12104
|
var richlistItemDirective = ({ props, renderSlot }) => {
|
|
12094
12105
|
const li = document.createElement("li");
|
|
12095
12106
|
li.className = "nr-richlist__item";
|
|
12096
|
-
|
|
12097
|
-
if (props.style) li.setAttribute("style", props.style);
|
|
12107
|
+
applyBaseProps(li, props);
|
|
12098
12108
|
if (props.image) {
|
|
12099
12109
|
const thumb = document.createElement("div");
|
|
12100
12110
|
thumb.className = "nr-richlist__thumb";
|
|
@@ -12156,36 +12166,20 @@ var richlistItemDirective = ({ props, renderSlot }) => {
|
|
|
12156
12166
|
var richlistDirective = ({ props, renderSlot }) => {
|
|
12157
12167
|
const ul = document.createElement("ul");
|
|
12158
12168
|
ul.className = "nr-richlist";
|
|
12159
|
-
|
|
12160
|
-
if (props.style) ul.setAttribute("style", props.style);
|
|
12169
|
+
applyBaseProps(ul, props);
|
|
12161
12170
|
ul.appendChild(renderSlot("default"));
|
|
12162
12171
|
return ul;
|
|
12163
12172
|
};
|
|
12164
12173
|
var richlist_default = richlistDirective;
|
|
12165
12174
|
|
|
12166
12175
|
// vanilla/directives/stat.ts
|
|
12167
|
-
var STAT_THEME_TOKENS = /* @__PURE__ */ new Set([
|
|
12168
|
-
"primary",
|
|
12169
|
-
"secondary",
|
|
12170
|
-
"info",
|
|
12171
|
-
"success",
|
|
12172
|
-
"warning",
|
|
12173
|
-
"error"
|
|
12174
|
-
]);
|
|
12175
|
-
function isArbitraryColor2(value) {
|
|
12176
|
-
if (STAT_THEME_TOKENS.has(value)) return false;
|
|
12177
|
-
if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
|
|
12178
|
-
if (/^[a-zA-Z]+$/.test(value)) return true;
|
|
12179
|
-
return false;
|
|
12180
|
-
}
|
|
12181
12176
|
var statDirective = ({ props }) => {
|
|
12182
|
-
const
|
|
12183
|
-
const colorClass =
|
|
12177
|
+
const statIsThemeToken = isThemeToken(props.color);
|
|
12178
|
+
const colorClass = statIsThemeToken ? ` nr-stat--${props.color}` : "";
|
|
12184
12179
|
const stat = document.createElement("div");
|
|
12185
12180
|
stat.className = `nr-stat${colorClass}`;
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
const useInlineColor = props.color && isArbitraryColor2(props.color) && !isThemeToken;
|
|
12181
|
+
applyBaseProps(stat, props);
|
|
12182
|
+
const useInlineColor = props.color && isArbitraryColor(props.color) && !statIsThemeToken;
|
|
12189
12183
|
if (props.icon) {
|
|
12190
12184
|
const figure = document.createElement("div");
|
|
12191
12185
|
figure.className = "nr-stat__figure";
|
|
@@ -12278,9 +12272,12 @@ function renderHtmlString(html) {
|
|
|
12278
12272
|
processedContent = processedContent.replace(
|
|
12279
12273
|
/<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
|
|
12280
12274
|
(_match, cssContent) => {
|
|
12275
|
+
const trimmed = cssContent.trim();
|
|
12276
|
+
const existing = document.head.querySelector("style[data-nr-global]");
|
|
12277
|
+
if (existing && existing.textContent === trimmed) return "";
|
|
12281
12278
|
const styleEl = document.createElement("style");
|
|
12282
12279
|
styleEl.setAttribute("data-nr-global", "");
|
|
12283
|
-
styleEl.textContent =
|
|
12280
|
+
styleEl.textContent = trimmed;
|
|
12284
12281
|
document.head.appendChild(styleEl);
|
|
12285
12282
|
return "";
|
|
12286
12283
|
}
|
|
@@ -12350,19 +12347,14 @@ function renderElement(element, ctx, allElements) {
|
|
|
12350
12347
|
switch (element.type) {
|
|
12351
12348
|
case "header": {
|
|
12352
12349
|
const tag = `h${element.level}`;
|
|
12353
|
-
let text = element.text;
|
|
12354
|
-
const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
|
|
12355
|
-
const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
|
|
12356
|
-
if (alignCenter) text = alignCenter[1];
|
|
12357
|
-
else if (alignRight) text = alignRight[1];
|
|
12358
12350
|
const h = document.createElement(tag);
|
|
12359
12351
|
h.id = element.id;
|
|
12360
12352
|
let cls = `md-h${element.level}`;
|
|
12361
|
-
if (
|
|
12362
|
-
if (
|
|
12353
|
+
if (element.align === "center") cls += " text-center";
|
|
12354
|
+
else if (element.align === "right") cls += " text-right";
|
|
12363
12355
|
if (element.classes) cls += ` ${element.classes}`;
|
|
12364
12356
|
h.className = cls;
|
|
12365
|
-
h.appendChild(renderInline(text));
|
|
12357
|
+
h.appendChild(renderInline(element.text));
|
|
12366
12358
|
return h;
|
|
12367
12359
|
}
|
|
12368
12360
|
case "paragraph": {
|
|
@@ -12921,7 +12913,7 @@ var guideData = [
|
|
|
12921
12913
|
"title": "Modal",
|
|
12922
12914
|
"icon": "open_in_full",
|
|
12923
12915
|
"order": 2,
|
|
12924
|
-
"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 (
|
|
12916
|
+
"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.'
|
|
12925
12917
|
},
|
|
12926
12918
|
{
|
|
12927
12919
|
"id": "button",
|
|
@@ -12929,7 +12921,7 @@ var guideData = [
|
|
|
12929
12921
|
"title": "Button",
|
|
12930
12922
|
"icon": "touch_app",
|
|
12931
12923
|
"order": 3,
|
|
12932
|
-
"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` / `_self` / ... | Destino del enlace (default `_blank`) |\n| `class` | texto | Clases CSS adicionales |'
|
|
12924
|
+
"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 |'
|
|
12933
12925
|
},
|
|
12934
12926
|
{
|
|
12935
12927
|
"id": "slide",
|