@noirmd/previewer 2.1.5 → 2.1.6

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/react.cjs CHANGED
@@ -11080,6 +11080,7 @@ function createModal(title) {
11080
11080
  header.appendChild(titleEl);
11081
11081
  const closeBtn = document.createElement("button");
11082
11082
  closeBtn.className = "nr-modal__close";
11083
+ closeBtn.setAttribute("aria-label", "Close");
11083
11084
  closeBtn.appendChild(createIcon("close"));
11084
11085
  closeBtn.addEventListener("click", () => dialog.close());
11085
11086
  header.appendChild(closeBtn);
@@ -11361,6 +11362,18 @@ function openModal(dialog) {
11361
11362
  }
11362
11363
  }
11363
11364
  var IMG_RE = /!\[([^\]]*)\]\(([^)]+)\)/g;
11365
+ function applyAlignClass(el, baseClass, align) {
11366
+ if (align === "center") {
11367
+ el.classList.add(`${baseClass}--center`);
11368
+ } else if (align === "right") {
11369
+ el.classList.add(`${baseClass}--right`);
11370
+ }
11371
+ }
11372
+ function resolveIcon(value, fallback) {
11373
+ if (!value) return fallback;
11374
+ if (value === "none" || value === "off") return null;
11375
+ return value;
11376
+ }
11364
11377
  function parseIntProp(value, defaultValue) {
11365
11378
  if (!value) return defaultValue;
11366
11379
  const n = parseInt(value, 10);
@@ -11400,13 +11413,16 @@ var modalDirective = ({ props, renderSlot }) => {
11400
11413
  const label = props.label || props.title || "Open";
11401
11414
  const modalTitle = props.title || "Modal";
11402
11415
  const align = props.align || "left";
11416
+ const iconName = resolveIcon(props.icon, "open_in_full");
11403
11417
  const wrapper = document.createElement("div");
11404
- wrapper.className = `nr-modal-trigger${align === "center" ? " nr-modal-trigger--center" : align === "right" ? " nr-modal-trigger--right" : ""}`;
11418
+ wrapper.className = "nr-modal-trigger";
11419
+ applyAlignClass(wrapper, "nr-modal-trigger", align);
11405
11420
  const btn = document.createElement("button");
11406
- btn.className = `nr-button nr-button--default`;
11421
+ btn.className = "nr-button nr-button--default";
11422
+ btn.setAttribute("aria-haspopup", "dialog");
11423
+ applyColor(btn, props.color, "nr-button");
11407
11424
  applyBaseProps(btn, props);
11408
- const icon = props.icon || "open_in_new";
11409
- if (icon) btn.appendChild(createIcon(icon));
11425
+ if (iconName) btn.appendChild(createIcon(iconName));
11410
11426
  btn.appendChild(document.createTextNode(label));
11411
11427
  const dialog = createModal(modalTitle);
11412
11428
  const body = dialog.querySelector(".nr-modal__body");
@@ -11427,20 +11443,21 @@ var modal_default = modalDirective;
11427
11443
  var buttonDirective = ({ props, renderSlot }) => {
11428
11444
  const url = props.url || props.href || "#";
11429
11445
  const label = props.label || props.title;
11430
- const icon = props.icon || "near_me";
11446
+ const iconName = resolveIcon(props.icon, "touch_app");
11431
11447
  const target = props.target || "_blank";
11432
- const customClass = props.class || "";
11433
11448
  const align = props.align || "left";
11434
11449
  const wrapper = document.createElement("div");
11435
- wrapper.className = `nr-button-wrap${align === "center" ? " nr-button-wrap--center" : align === "right" ? " nr-button-wrap--right" : ""}`;
11450
+ wrapper.className = "nr-button-wrap";
11451
+ applyAlignClass(wrapper, "nr-button-wrap", align);
11436
11452
  if (label) {
11437
11453
  const a = document.createElement("a");
11438
11454
  a.href = url;
11439
11455
  a.target = target;
11440
- a.rel = "noopener noreferrer";
11456
+ if (target === "_blank") a.rel = "noopener noreferrer";
11441
11457
  a.className = "nr-button nr-button--default";
11458
+ applyColor(a, props.color, "nr-button");
11442
11459
  applyBaseProps(a, props);
11443
- a.appendChild(createIcon(icon));
11460
+ if (iconName) a.appendChild(createIcon(iconName));
11444
11461
  a.appendChild(document.createTextNode(label));
11445
11462
  wrapper.appendChild(a);
11446
11463
  return wrapper;
@@ -11450,6 +11467,8 @@ var buttonDirective = ({ props, renderSlot }) => {
11450
11467
  if (links.length > 0) {
11451
11468
  links.forEach((link) => {
11452
11469
  link.classList.add("nr-button", "nr-button--default");
11470
+ applyColor(link, props.color, "nr-button");
11471
+ if (iconName) link.prepend(createIcon(iconName));
11453
11472
  applyBaseProps(link, props);
11454
11473
  });
11455
11474
  wrapper.appendChild(slotContent);
@@ -11457,10 +11476,11 @@ var buttonDirective = ({ props, renderSlot }) => {
11457
11476
  const a = document.createElement("a");
11458
11477
  a.href = url;
11459
11478
  a.target = target;
11460
- a.rel = "noopener noreferrer";
11479
+ if (target === "_blank") a.rel = "noopener noreferrer";
11461
11480
  a.className = "nr-button nr-button--default";
11481
+ applyColor(a, props.color, "nr-button");
11462
11482
  applyBaseProps(a, props);
11463
- a.appendChild(createIcon(icon));
11483
+ if (iconName) a.appendChild(createIcon(iconName));
11464
11484
  a.appendChild(slotContent);
11465
11485
  wrapper.appendChild(a);
11466
11486
  }
@@ -12719,7 +12739,7 @@ var guideData = [
12719
12739
  "title": "Introducci\xF3n",
12720
12740
  "icon": "menu_book",
12721
12741
  "order": 1,
12722
- "md": '# Introducci\xF3n a NoirMD\n\n**NoirMD** es un editor y motor de renderizado Markdown con extensiones propias: **admoniciones**, **componentes**, **directivas interactivas** y **markdown enriquecido**.\n\nEsta gu\xEDa est\xE1 escrita con el propio motor: cada directiva que ves aqu\xED es una muestra **viva** y funcional, no una captura.\n\n## C\xF3mo usar el editor\n\n| Elemento | Descripci\xF3n |\n| --- | --- |\n| Toolbar superior | Modo (editor / split / preview), guardar, copiar, imprimir, tema, gu\xEDa y configurar |\n| Panel izquierdo | Editor de c\xF3digo con resaltado de sintaxis |\n| Panel derecho | Preview en vivo (en modo split o preview) |\n| Atajo | `Ctrl+S` guarda el contenido |\n\n## Sintaxis de una directiva\n\nLas directivas se escriben con tres dos puntos `:::` y un nombre, opcionalmente con atributos entre llaves:\n\n```\n:::card {title="Mi tarjeta" icon="star"}\n\nContenido **markdown** aqu\xED dentro.\n\n:::\n```\n\nTodo lo que est\xE1 entre la apertura y el cierre `:::` se renderiza con el mismo motor, as\xED que puedes **anidar** directivas.\n\n## Cheatsheet r\xE1pido\n\n| Sintaxis | Resultado |\n| --- | --- |\n| `# T\xEDtulo` \u2192 `###### T\xEDtulo` | Encabezados |\n| `**negrita**` \xB7 `*cursiva*` \xB7 `~~tachado~~` | \xC9nfasis |\n| `` `c\xF3digo` `` | C\xF3digo inline |\n| `` ```js `` | Bloque de c\xF3digo con resaltado |\n| `[texto](url)` | Enlace |\n| `![alt](url)` | Imagen |\n| `![alt](url#left)` | Imagen flotante a la izquierda |\n| `==resaltado==` | Resaltado |\n| `%color%texto%%` | Texto de color |\n| `->centrado<-` | Texto centrado |\n| `!>spoiler<!` | Spoiler oculto |\n| `|[[icono]]|` | Icono Material |\n| `[TOC]` | \xCDndice de contenidos |\n| `:::note` `:::warning` `:::danger` `:::info` `:::greentext` | Admoniciones |\n| `:::card` `:::accordion` `:::carousel` `:::diff` `:::chat` `:::stat` `:::countdown` `:::keys` `:::hover-3d` `:::hover-gallery` `:::richlist` | Componentes |\n| `:::details` `:::modal` `:::button` `:::slide` | Interactivos |\n| `<style>` HTML inline | Bloques HTML (CSS global, HTML crudo) |\n\n## Organizaci\xF3n de la gu\xEDa\n\n- **Markdown** \u2014 sintaxis base y enriquecida (t\xEDtulos, \xE9nfasis, tablas, c\xF3digo, im\xE1genes, inline).\n- **Admoniciones** \u2014 cajas de aviso: nota, warning, danger, info y greentext.\n- **Componentes** \u2014 los 10 componentes de tarjeta, teclas, acorde\xF3n, carrusel, etc.\n- **Interactivos** \u2014 details, modal, botones y slides.\n- **Layout** \u2014 bloques HTML crudo: CSS global con `<style>` e HTML inline.\n\nCada p\xE1gina incluye: la sintaxis exacta, la tabla de props, un ejemplo en vivo y el c\xF3digo fuente para copiar.'
12742
+ "md": '# Introducci\xF3n a NoirMD\n\n**NoirMD** es un editor y motor de renderizado Markdown con extensiones propias: **admoniciones**, **componentes**, **directivas interactivas** y **markdown enriquecido**.\n\nEsta gu\xEDa est\xE1 escrita con el propio motor: cada directiva que ves aqu\xED es una muestra **viva** y funcional, no una captura.\n\n## C\xF3mo usar el editor\n\n| Elemento | Descripci\xF3n |\n| --- | --- |\n| Toolbar superior | Modo (editor / split / preview), guardar, copiar, imprimir, tema, gu\xEDa y configurar |\n| Panel izquierdo | Editor de c\xF3digo con resaltado de sintaxis |\n| Panel derecho | Preview en vivo (en modo split o preview) |\n| Atajo | `Ctrl+S` guarda el contenido |\n\n## Sintaxis de una directiva\n\nLas directivas se escriben con tres dos puntos `:::` y un nombre, opcionalmente con atributos entre llaves:\n\n```\n:::card {title="Mi tarjeta" icon="star"}\n\nContenido **markdown** aqu\xED dentro.\n\n:::\n```\n\nTodo lo que est\xE1 entre la apertura y el cierre `:::` se renderiza con el mismo motor, as\xED que puedes **anidar** directivas.\n\n## Cheatsheet r\xE1pido\n\n| Sintaxis | Resultado |\n| --- | --- |\n| `# T\xEDtulo` \u2192 `###### T\xEDtulo` | Encabezados |\n| `**negrita**` \xB7 `_cursiva_` \xB7 `~~tachado~~` | \xC9nfasis |\n| `` `c\xF3digo` `` | C\xF3digo inline |\n| `` ```js `` | Bloque de c\xF3digo con resaltado |\n| `[texto](url)` | Enlace |\n| `![alt](url)` | Imagen |\n| `![alt](url#left)` | Imagen flotante a la izquierda |\n| `==resaltado==` | Resaltado |\n| `%color%texto%%` | Texto de color |\n| `->centrado<-` | Texto centrado |\n| `!>spoiler<!` | Spoiler oculto |\n| `|[[icono]]|` | Icono Material |\n| `[TOC]` | \xCDndice de contenidos |\n| `:::note` `:::warning` `:::danger` `:::info` `:::greentext` | Admoniciones |\n| `:::card` `:::accordion` `:::carousel` `:::diff` `:::chat` `:::stat` `:::countdown` `:::keys` `:::hover-3d` `:::hover-gallery` `:::richlist` | Componentes |\n| `:::details` `:::modal` `:::button` `:::slide` | Interactivos |\n| `<style>` HTML inline | Bloques HTML (CSS global, HTML crudo) |\n\n## Organizaci\xF3n de la gu\xEDa\n\n- **Markdown** \u2014 sintaxis base y enriquecida (t\xEDtulos, \xE9nfasis, tablas, c\xF3digo, im\xE1genes, inline).\n- **Admoniciones** \u2014 cajas de aviso: nota, warning, danger, info y greentext.\n- **Componentes** \u2014 los 10 componentes de tarjeta, teclas, acorde\xF3n, carrusel, etc.\n- **Interactivos** \u2014 details, modal, botones y slides.\n- **Layout** \u2014 bloques HTML crudo: CSS global con `<style>` e HTML inline.\n\nCada p\xE1gina incluye: la sintaxis exacta, la tabla de props, un ejemplo en vivo y el c\xF3digo fuente para copiar.'
12723
12743
  },
12724
12744
  {
12725
12745
  "id": "titulos",
@@ -12935,7 +12955,7 @@ var guideData = [
12935
12955
  "title": "Modal",
12936
12956
  "icon": "open_in_full",
12937
12957
  "order": 2,
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.'
12958
+ "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## Sin icono\n\nPara ocultar el icono del bot\xF3n de apertura, usa `icon="none"`:\n\n```md\n:::modal {title="Sin icono" label="Abrir" icon="none"}\nContenido del modal.\n:::\n```\n\n:::modal {title="Sin icono" label="Abrir" icon="none"}\nContenido del modal.\n:::\n\n## Color\n\nEl bot\xF3n de apertura acepta tokens de tema (`primary`, `secondary`, `info`, `success`, `warning`, `error`) o colores CSS arbitrarios:\n\n```md\n:::modal {title="\xC9xito" label="Abrir" icon="check_circle" color="success"}\nAcci\xF3n completada correctamente.\n:::\n```\n\n:::modal {title="\xC9xito" label="Abrir" icon="check_circle" color="success"}\nAcci\xF3n completada correctamente.\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_full`). Usa `icon="none"` para ocultar |\n| `color` | token de tema o CSS | Color del bot\xF3n de apertura |\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del bot\xF3n de apertura (default `left`) |\n| `class` | texto | Clases CSS adicionales (se aplican al bot\xF3n de apertura) |\n| `style` | CSS | Estilos inline (se aplican al bot\xF3n de apertura) |\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.'
12939
12959
  },
12940
12960
  {
12941
12961
  "id": "button",
@@ -12943,7 +12963,7 @@ var guideData = [
12943
12963
  "title": "Button",
12944
12964
  "icon": "touch_app",
12945
12965
  "order": 3,
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 |'
12966
+ "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. El icono se a\xF1ade autom\xE1ticamente a cada enlace del contenido:\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## Con enlace en el contenido\n\nSi el contenido es un enlace markdown, el bot\xF3n usa el enlace del contenido y el icono se a\xF1ade al principio:\n\n```md\n:::button {icon="star"}\n[Descarga con FDM](https://example.com/download)\n:::\n```\n\n:::button {icon="star"}\n[Descarga con FDM](https://example.com/download)\n:::\n\n## Sin icono\n\nPara ocultar el icono, usa `icon="none"`:\n\n```md\n:::button {label="Sin icono" url="https://example.com" icon="none"}\n:::\n```\n\n:::button {label="Sin icono" url="https://example.com" icon="none"}\n:::\n\n## Color\n\nLos botones aceptan tokens de tema (`primary`, `secondary`, `info`, `success`, `warning`, `error`) o colores CSS arbitrarios (`red`, `#ff0000`, `rgb(255,0,0)`):\n\n```md\n:::button {label="\xC9xito" url="https://example.com" icon="check_circle" color="success"}\n:::\n```\n\n:::button {label="\xC9xito" url="https://example.com" icon="check_circle" color="success"}\n:::\n\n```md\n:::button {label="Rojo" url="https://example.com" icon="error" color="#e11d48"}\n:::\n```\n\n:::button {label="Rojo" url="https://example.com" icon="error" color="#e11d48"}\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 `touch_app`). Usa `icon="none"` para ocultar |\n| `target` | `_blank` / `_self` / ... | Destino del enlace (default `_blank`) |\n| `color` | token de tema o CSS | Color del bot\xF3n (ver colores soportados arriba) |\n| `align` | `left` / `center` / `right` | Alineaci\xF3n del bot\xF3n (default `left`) |\n| `class` | texto | Clases CSS adicionales |\n| `style` | CSS | Estilos inline (ej: `style="font-size:1rem"`) |'
12947
12967
  },
12948
12968
  {
12949
12969
  "id": "slide",
@@ -12960,6 +12980,14 @@ var guideData = [
12960
12980
  "icon": "code_off",
12961
12981
  "order": 1,
12962
12982
  "md": '# Bloques HTML\r\n\r\nNoirMD permite escribir **HTML crudo** directamente en el markdown. Seg\xFAn la etiqueta, el comportamiento var\xEDa.\r\n\r\n## CSS global con `<style>`\r\n\r\nEscribe un bloque `<style>` para inyectar CSS en el documento. El contenido se extrae autom\xE1ticamente y se inserta en el `<head>` del DOM.\r\n\r\n```md\r\n<style>\r\n.mi-clase {\r\n background: #f1f5f9;\r\n border-radius: 10px;\r\n padding: 1rem;\r\n}\r\n</style>\r\n```\r\n\r\n<style>\r\n.nr-demo-box {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 1rem;\r\n padding: 1rem;\r\n border-radius: 12px;\r\n background: color-mix(in srgb, var(--color-accent-primary, #0ea5e9) 10%, transparent);\r\n}\r\n.nr-demo-box > div {\r\n padding: 1rem;\r\n border-radius: 8px;\r\n background: var(--color-background-secondary-solid, #1e293b);\r\n}\r\n</style>\r\n\r\n<div class="nr-demo-box">\r\n<div>**A**</div>\r\n<div>**B**</div>\r\n</div>\r\n\r\n> El CSS se aplica al **documento renderizado completo**, no solo al bloque. Define clases una vez y \xFAsalas despu\xE9s en cualquier etiqueta HTML.\r\n\r\n## HTML inline\r\n\r\nCualquier etiqueta HTML escrita directamente en el markdown se renderiza sin procesar como markdown. El contenido dentro se preserva tal cual.\r\n\r\n```md\r\n<div style="text-align: center; padding: 1rem; border: 1px solid #334155; border-radius: 10px;">\r\n HTML escrito a mano funciona tal cual.\r\n</div>\r\n```\r\n\r\n<div style="text-align: center; padding: 1rem; border: 1px solid #334155; border-radius: 10px;">\r\n HTML escrito a mano funciona tal cual.\r\n</div>\r\n\r\n## Elementos interactivos nativos\r\n\r\n```md\r\n<details class="nr-details">\r\n <summary>Detalle nativo con <b>HTML</b></summary>\r\n <p>Los atributos, estilos y eventos se conservan intactos.</p>\r\n</details>\r\n```\r\n\r\n<details class="nr-details">\r\n <summary>Detalle nativo con <b>HTML</b></summary>\r\n <p>Los atributos, estilos y eventos se conservan intactos.</p>\r\n</details>\r\n\r\n## Scripts\r\n\r\nLos bloques `<script>` se ejecutan autom\xE1ticamente al renderizar:\r\n\r\n```md\r\n<script>\r\n console.log(\'Este script se ejecuta al renderizar\');\r\n</script>\r\n```\r\n\r\n> \u26A0\uFE0F Al ser HTML y scripts sin filtrar, \xFAsalos solo con contenido de confianza.\r\n\r\n## Cu\xE1ndo usar bloques HTML\r\n\r\n- Insertar embeds (`iframe`, `video`, widgets externos).\r\n- Estructuras que el markdown no cubre (layouts complejos, formularios nativos).\r\n- Inyectar CSS reutilizable con `<style>`.\r\n- Prototipar HTML antes de convertirlo a directiva.'
12983
+ },
12984
+ {
12985
+ "id": "wrapper-directives",
12986
+ "category": "Layout",
12987
+ "title": "Wrapper Directives",
12988
+ "icon": "crop_free",
12989
+ "order": 1,
12990
+ "md": '# Wrapper Directives\r\n\r\nLas directivas `:::div`, `:::style`, `:::custom` y `:::raw` son wrappers gen\xE9ricos para **envolver contenido** con clases, estilos y atributos personalizados.\r\n\r\n## `:::div` \u2014 Div gen\xE9rico\r\n\r\nEnvuelve contenido en un `<div>` con clases, id, estilos y atributos `data-*`.\r\n\r\n```md\r\n:::div {class="mi-clase" id="seccion" style="padding: 2rem; background: #f0f0f0"}\r\n\r\nContenido **markdown** aqu\xED.\r\n\r\n:::\r\n```\r\n\r\n:::div {class="mi-clase" id="seccion" style="padding: 2rem; background: #f0f0f0"}\r\n\r\nContenido **markdown** aqu\xED.\r\n\r\n:::\r\n\r\n## `:::style` \u2014 Inyectar CSS\r\n\r\nInyecta un bloque `<style>` global. \xDAtil para estilos que afectan m\xFAltiples componentes.\r\n\r\n```md\r\n:::style\r\n.nr-mi-clase { color: red; }\r\n:::\r\n```\r\n\r\n## `:::custom` \u2014 Elemento personalizado\r\n\r\nSimilar a `div`, pero permite crear cualquier elemento HTML.\r\n\r\n## `:::raw` \u2014 HTML crudo\r\n\r\nRenderiza contenido HTML sin procesar.\r\n\r\n## Props\r\n\r\n| Prop | Tipo | Descripci\xF3n |\r\n| --- | --- | --- |\r\n| `class` | texto | Clases CSS (soporta `.shorthand` tambi\xE9n) |\r\n| `id` | texto | ID del elemento |\r\n| `style` | CSS inline | Estilos inline (se aplica con `setProperty`, no sobreescribe otros estilos) |\r\n| `data-*` | texto | Cualquier atributo `data-*` se aplica al elemento |\r\n\r\n## Shorthands\r\n\r\n```md\r\n:::div {.mi-clase #mi-id}\r\n\r\nIgual que usar `class="mi-clase" id="mi-id"`.\r\n\r\n:::\r\n```'
12963
12991
  }
12964
12992
  ];
12965
12993