@wireweave/core 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -8352,6 +8352,14 @@ ${children}
8352
8352
  }
8353
8353
 
8354
8354
  // src/renderer/html/renderers/container.ts
8355
+ function buildInteractiveAttrs(node) {
8356
+ return {
8357
+ "data-navigate": node.navigate,
8358
+ "data-opens": node.opens,
8359
+ "data-toggles": node.toggles,
8360
+ "data-action": node.action
8361
+ };
8362
+ }
8355
8363
  function renderCard(node, ctx) {
8356
8364
  const hasExplicitWidth = node.w !== void 0;
8357
8365
  const classes = ctx.buildClassString([
@@ -8362,10 +8370,12 @@ function renderCard(node, ctx) {
8362
8370
  ]);
8363
8371
  const styles = ctx.buildCommonStyles(node);
8364
8372
  const styleAttr = styles ? ` style="${styles}"` : "";
8373
+ const interactiveAttrs = buildInteractiveAttrs(node);
8374
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
8365
8375
  const title = node.title ? `<h3 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h3>
8366
8376
  ` : "";
8367
8377
  const children = ctx.renderChildren(node.children);
8368
- return `<div class="${classes}"${styleAttr}>
8378
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr}>
8369
8379
  ${title}${children}
8370
8380
  </div>`;
8371
8381
  }
@@ -8376,10 +8386,11 @@ function renderModal(node, ctx) {
8376
8386
  ]);
8377
8387
  const styles = ctx.buildCommonStyles(node);
8378
8388
  const styleAttr = styles ? ` style="${styles}"` : "";
8389
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
8379
8390
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
8380
8391
  ` : "";
8381
8392
  const children = ctx.renderChildren(node.children);
8382
- return `<div class="${ctx.prefix}-modal-backdrop">
8393
+ return `<div class="${ctx.prefix}-modal-backdrop"${idAttr}>
8383
8394
  <div class="${classes}"${styleAttr} role="dialog" aria-modal="true">
8384
8395
  ${title}${children}
8385
8396
  </div>
@@ -8394,10 +8405,11 @@ function renderDrawer(node, ctx) {
8394
8405
  ]);
8395
8406
  const styles = ctx.buildCommonStyles(node);
8396
8407
  const styleAttr = styles ? ` style="${styles}"` : "";
8408
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
8397
8409
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
8398
8410
  ` : "";
8399
8411
  const children = ctx.renderChildren(node.children);
8400
- return `<aside class="${classes}"${styleAttr}>
8412
+ return `<aside class="${classes}"${styleAttr}${idAttr}>
8401
8413
  ${title}${children}
8402
8414
  </aside>`;
8403
8415
  }
@@ -8454,7 +8466,12 @@ function renderLink(node, ctx) {
8454
8466
  const styleAttr = styles ? ` style="${styles}"` : "";
8455
8467
  const attrs = {
8456
8468
  class: classes,
8457
- href: node.href || "#"
8469
+ href: node.href || node.navigate || "#",
8470
+ // Interactive attributes
8471
+ "data-navigate": node.navigate,
8472
+ "data-opens": node.opens,
8473
+ "data-toggles": node.toggles,
8474
+ "data-action": node.action
8458
8475
  };
8459
8476
  if (node.external) {
8460
8477
  attrs.target = "_blank";
@@ -54882,7 +54899,12 @@ function renderButton(node, ctx) {
54882
54899
  const styleAttr = styles ? ` style="${styles}"` : "";
54883
54900
  const attrs = {
54884
54901
  class: classes,
54885
- disabled: node.disabled
54902
+ disabled: node.disabled,
54903
+ // Interactive attributes
54904
+ "data-navigate": node.navigate,
54905
+ "data-opens": node.opens,
54906
+ "data-toggles": node.toggles,
54907
+ "data-action": node.action
54886
54908
  };
54887
54909
  let icon = "";
54888
54910
  if (node.icon) {
@@ -55124,6 +55146,14 @@ ${slider}`;
55124
55146
  }
55125
55147
 
55126
55148
  // src/renderer/html/renderers/display.ts
55149
+ function buildInteractiveAttrs2(node) {
55150
+ return {
55151
+ "data-navigate": node.navigate,
55152
+ "data-opens": node.opens,
55153
+ "data-toggles": node.toggles,
55154
+ "data-action": node.action
55155
+ };
55156
+ }
55127
55157
  function renderImage(node, ctx) {
55128
55158
  const classes = ctx.buildClassString([
55129
55159
  `${ctx.prefix}-image`,
@@ -55135,14 +55165,17 @@ function renderImage(node, ctx) {
55135
55165
  const attrs = {
55136
55166
  class: classes,
55137
55167
  src: node.src,
55138
- alt: node.alt || "Image"
55168
+ alt: node.alt || "Image",
55169
+ ...buildInteractiveAttrs2(node)
55139
55170
  };
55140
55171
  const imgStyleAttr = styles ? `; ${styles}` : "";
55141
55172
  return `<img${ctx.buildAttrsString(attrs)}${imgStyleAttr ? ` style="${imgStyleAttr.slice(2)}"` : ""} />`;
55142
55173
  }
55143
55174
  const label = node.alt || "Image";
55144
55175
  const icon = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
55145
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
55176
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55177
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55178
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
55146
55179
  }
55147
55180
  function renderPlaceholder(node, ctx) {
55148
55181
  const classes = ctx.buildClassString([
@@ -55174,9 +55207,13 @@ function renderAvatar(node, ctx) {
55174
55207
  const combinedStyles = baseStyles && sizeStyle ? `${baseStyles}; ${sizeStyle}` : baseStyles || sizeStyle;
55175
55208
  const styleAttr = combinedStyles ? ` style="${combinedStyles}"` : "";
55176
55209
  const initials = node.name ? node.name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
55177
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
55210
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55211
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55212
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
55178
55213
  }
55179
55214
  function renderBadge(node, ctx) {
55215
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55216
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55180
55217
  if (node.icon) {
55181
55218
  const iconData = getIconData(node.icon);
55182
55219
  const classes2 = ctx.buildClassString([
@@ -55189,9 +55226,9 @@ function renderBadge(node, ctx) {
55189
55226
  const styleAttr2 = styles2 ? ` style="${styles2}"` : "";
55190
55227
  if (iconData) {
55191
55228
  const svg = renderIconSvg(iconData, 24, 2, `${ctx.prefix}-icon`);
55192
- return `<span class="${classes2}"${styleAttr2} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
55229
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
55193
55230
  }
55194
- return `<span class="${classes2}"${styleAttr2} aria-label="unknown icon">?</span>`;
55231
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="unknown icon">?</span>`;
55195
55232
  }
55196
55233
  const isDot = !node.content || node.content.trim() === "";
55197
55234
  const classes = ctx.buildClassString([
@@ -55203,10 +55240,12 @@ function renderBadge(node, ctx) {
55203
55240
  ]);
55204
55241
  const styles = ctx.buildCommonStyles(node);
55205
55242
  const styleAttr = styles ? ` style="${styles}"` : "";
55206
- return `<span class="${classes}"${styleAttr}>${ctx.escapeHtml(node.content)}</span>`;
55243
+ return `<span class="${classes}"${styleAttr}${interactiveAttrStr}>${ctx.escapeHtml(node.content)}</span>`;
55207
55244
  }
55208
55245
  function renderIcon(node, ctx) {
55209
55246
  const iconData = getIconData(node.name);
55247
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55248
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55210
55249
  const sizeResolved = resolveSizeValue(node.size, "icon", ctx.prefix);
55211
55250
  const wrapperClasses = ctx.buildClassString([
55212
55251
  `${ctx.prefix}-icon-wrapper`,
@@ -55222,7 +55261,7 @@ function renderIcon(node, ctx) {
55222
55261
  const svgStyleAttr = sizeResolved.style ? ` style="${sizeResolved.style}"` : "";
55223
55262
  const svg = renderIconSvg(iconData, 24, 2, iconClasses, svgStyleAttr);
55224
55263
  const wrapperStyleAttr2 = baseStyles ? ` style="${baseStyles}"` : "";
55225
- return `<span class="${wrapperClasses}"${wrapperStyleAttr2} aria-hidden="true">${svg}</span>`;
55264
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr2}${interactiveAttrStr} aria-hidden="true">${svg}</span>`;
55226
55265
  }
55227
55266
  const size = sizeResolved.style?.match(/(\d+)px/)?.[1] || "24";
55228
55267
  const sizeNum = parseInt(size, 10);
@@ -55231,7 +55270,7 @@ function renderIcon(node, ctx) {
55231
55270
  <text x="12" y="16" text-anchor="middle" font-size="10" fill="currentColor" opacity="0.7">?</text>
55232
55271
  </svg>`;
55233
55272
  const wrapperStyleAttr = baseStyles ? ` style="${baseStyles}"` : "";
55234
- return `<span class="${wrapperClasses}"${wrapperStyleAttr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
55273
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr}${interactiveAttrStr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
55235
55274
  }
55236
55275
 
55237
55276
  // src/renderer/html/renderers/overlay.ts
@@ -55282,7 +55321,20 @@ function renderDropdown(node, ctx) {
55282
55321
  dropdownItem.danger ? `${ctx.prefix}-dropdown-item-danger` : void 0,
55283
55322
  dropdownItem.disabled ? `${ctx.prefix}-dropdown-item-disabled` : void 0
55284
55323
  ]);
55285
- return `<button class="${itemClasses}"${dropdownItem.disabled ? ' disabled="disabled"' : ""}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
55324
+ const interactiveAttrs = {
55325
+ "data-navigate": dropdownItem.navigate,
55326
+ "data-opens": dropdownItem.opens,
55327
+ "data-toggles": dropdownItem.toggles,
55328
+ "data-action": dropdownItem.action
55329
+ };
55330
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55331
+ const hrefAttr = dropdownItem.href ? ` href="${ctx.escapeHtml(dropdownItem.href)}"` : "";
55332
+ const disabledAttr = dropdownItem.disabled ? ' disabled="disabled"' : "";
55333
+ if (dropdownItem.href || dropdownItem.navigate) {
55334
+ const href = dropdownItem.href || dropdownItem.navigate || "#";
55335
+ return `<a class="${itemClasses}" href="${ctx.escapeHtml(href)}"${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</a>`;
55336
+ }
55337
+ return `<button class="${itemClasses}"${disabledAttr}${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
55286
55338
  }).join("\n");
55287
55339
  return `<div class="${classes}"${styleAttr}>
55288
55340
  ${items}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AnyNode, C as ContainerNode, L as LeafNode, a as LayoutNode, P as PageNode, H as HeaderNode, M as MainNode, F as FooterNode, S as SidebarNode, b as SectionNode, G as GridNode, R as RowNode, c as ColNode, d as ContainerComponentNode, e as CardNode, f as ModalNode, D as DrawerNode, g as AccordionNode, T as TextContentNode, h as TextNode, i as TitleNode, j as LinkNode, I as InputComponentNode, k as InputNode, l as TextareaNode, m as SelectNode, n as CheckboxNode, o as RadioNode, p as SwitchNode, q as SliderNode, B as ButtonNode, r as DisplayNode, s as ImageNode, t as PlaceholderNode, u as AvatarNode, v as BadgeNode, w as IconNode, x as DataNode, y as TableNode, z as ListNode, E as FeedbackNode, J as AlertNode, K as ToastNode, N as ProgressNode, O as SpinnerNode, Q as OverlayNode, U as TooltipNode, V as PopoverNode, W as DropdownNode, X as NavigationNode, Y as NavNode, Z as TabsNode, _ as BreadcrumbNode, $ as DividerComponentNode, a0 as NodeType, a1 as WireframeDocument } from './types-lcJzPcR0.cjs';
2
- export { ay as AlertVariant, ac as AlignValue, at as AvatarSize, av as BadgeSize, au as BadgeVariant, a4 as BaseNode, aK as BreadcrumbItem, as as ButtonSize, ar as ButtonVariant, ah as CommonProps, ad as DirectionValue, aD as DividerNode, aj as DrawerPosition, aC as DropdownItemNode, ae as FlexProps, af as GridProps, a9 as HeightValue, aw as IconSize, ap as InputType, ab as JustifyValue, ax as ListItemNode, aF as NavBlockItem, aI as NavChild, aH as NavDivider, aG as NavGroupNode, aE as NavItem, a2 as Position, ag as PositionProps, aq as SelectOption, ai as ShadowValue, aa as SizeProps, a3 as SourceLocation, a7 as SpacingProps, a6 as SpacingValue, aA as SpinnerSize, aJ as TabNode, an as TextAlign, al as TextSize, ak as TextSizeToken, am as TextWeight, ao as TitleLevel, az as ToastPosition, aB as TooltipPosition, a5 as ValueWithUnit, a8 as WidthValue } from './types-lcJzPcR0.cjs';
1
+ import { A as AnyNode, C as ContainerNode, L as LeafNode, a as LayoutNode, P as PageNode, H as HeaderNode, M as MainNode, F as FooterNode, S as SidebarNode, b as SectionNode, G as GridNode, R as RowNode, c as ColNode, d as ContainerComponentNode, e as CardNode, f as ModalNode, D as DrawerNode, g as AccordionNode, T as TextContentNode, h as TextNode, i as TitleNode, j as LinkNode, I as InputComponentNode, k as InputNode, l as TextareaNode, m as SelectNode, n as CheckboxNode, o as RadioNode, p as SwitchNode, q as SliderNode, B as ButtonNode, r as DisplayNode, s as ImageNode, t as PlaceholderNode, u as AvatarNode, v as BadgeNode, w as IconNode, x as DataNode, y as TableNode, z as ListNode, E as FeedbackNode, J as AlertNode, K as ToastNode, N as ProgressNode, O as SpinnerNode, Q as OverlayNode, U as TooltipNode, V as PopoverNode, W as DropdownNode, X as NavigationNode, Y as NavNode, Z as TabsNode, _ as BreadcrumbNode, $ as DividerComponentNode, a0 as NodeType, a1 as WireframeDocument } from './types-CRocJqKS.cjs';
2
+ export { az as AlertVariant, ac as AlignValue, au as AvatarSize, aw as BadgeSize, av as BadgeVariant, a4 as BaseNode, aL as BreadcrumbItem, at as ButtonSize, as as ButtonVariant, ah as CommonProps, ad as DirectionValue, aE as DividerNode, ak as DrawerPosition, aD as DropdownItemNode, ae as FlexProps, af as GridProps, a9 as HeightValue, ax as IconSize, aq as InputType, ai as InteractiveProps, ab as JustifyValue, ay as ListItemNode, aG as NavBlockItem, aJ as NavChild, aI as NavDivider, aH as NavGroupNode, aF as NavItem, a2 as Position, ag as PositionProps, ar as SelectOption, aj as ShadowValue, aa as SizeProps, a3 as SourceLocation, a7 as SpacingProps, a6 as SpacingValue, aB as SpinnerSize, aK as TabNode, ao as TextAlign, am as TextSize, al as TextSizeToken, an as TextWeight, ap as TitleLevel, aA as ToastPosition, aC as TooltipPosition, a5 as ValueWithUnit, a8 as WidthValue } from './types-CRocJqKS.cjs';
3
3
  export { ExpectedToken, ParseError, ParseErrorInfo, ParseOptions, ParseResult, getErrors, isValid, parse, tryParse } from './parser.cjs';
4
4
  export { HtmlRenderer, IconData, IconElement, RenderContext, RenderOptions, RenderResult, SvgRenderOptions, SvgRenderResult, ThemeColors, ThemeConfig, createHtmlRenderer, darkTheme, defaultTheme, generateComponentStyles, generateStyles, getIconData, getTheme, lucideIcons, render, renderIconSvg, renderToHtml, renderToSvg } from './renderer.cjs';
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AnyNode, C as ContainerNode, L as LeafNode, a as LayoutNode, P as PageNode, H as HeaderNode, M as MainNode, F as FooterNode, S as SidebarNode, b as SectionNode, G as GridNode, R as RowNode, c as ColNode, d as ContainerComponentNode, e as CardNode, f as ModalNode, D as DrawerNode, g as AccordionNode, T as TextContentNode, h as TextNode, i as TitleNode, j as LinkNode, I as InputComponentNode, k as InputNode, l as TextareaNode, m as SelectNode, n as CheckboxNode, o as RadioNode, p as SwitchNode, q as SliderNode, B as ButtonNode, r as DisplayNode, s as ImageNode, t as PlaceholderNode, u as AvatarNode, v as BadgeNode, w as IconNode, x as DataNode, y as TableNode, z as ListNode, E as FeedbackNode, J as AlertNode, K as ToastNode, N as ProgressNode, O as SpinnerNode, Q as OverlayNode, U as TooltipNode, V as PopoverNode, W as DropdownNode, X as NavigationNode, Y as NavNode, Z as TabsNode, _ as BreadcrumbNode, $ as DividerComponentNode, a0 as NodeType, a1 as WireframeDocument } from './types-lcJzPcR0.js';
2
- export { ay as AlertVariant, ac as AlignValue, at as AvatarSize, av as BadgeSize, au as BadgeVariant, a4 as BaseNode, aK as BreadcrumbItem, as as ButtonSize, ar as ButtonVariant, ah as CommonProps, ad as DirectionValue, aD as DividerNode, aj as DrawerPosition, aC as DropdownItemNode, ae as FlexProps, af as GridProps, a9 as HeightValue, aw as IconSize, ap as InputType, ab as JustifyValue, ax as ListItemNode, aF as NavBlockItem, aI as NavChild, aH as NavDivider, aG as NavGroupNode, aE as NavItem, a2 as Position, ag as PositionProps, aq as SelectOption, ai as ShadowValue, aa as SizeProps, a3 as SourceLocation, a7 as SpacingProps, a6 as SpacingValue, aA as SpinnerSize, aJ as TabNode, an as TextAlign, al as TextSize, ak as TextSizeToken, am as TextWeight, ao as TitleLevel, az as ToastPosition, aB as TooltipPosition, a5 as ValueWithUnit, a8 as WidthValue } from './types-lcJzPcR0.js';
1
+ import { A as AnyNode, C as ContainerNode, L as LeafNode, a as LayoutNode, P as PageNode, H as HeaderNode, M as MainNode, F as FooterNode, S as SidebarNode, b as SectionNode, G as GridNode, R as RowNode, c as ColNode, d as ContainerComponentNode, e as CardNode, f as ModalNode, D as DrawerNode, g as AccordionNode, T as TextContentNode, h as TextNode, i as TitleNode, j as LinkNode, I as InputComponentNode, k as InputNode, l as TextareaNode, m as SelectNode, n as CheckboxNode, o as RadioNode, p as SwitchNode, q as SliderNode, B as ButtonNode, r as DisplayNode, s as ImageNode, t as PlaceholderNode, u as AvatarNode, v as BadgeNode, w as IconNode, x as DataNode, y as TableNode, z as ListNode, E as FeedbackNode, J as AlertNode, K as ToastNode, N as ProgressNode, O as SpinnerNode, Q as OverlayNode, U as TooltipNode, V as PopoverNode, W as DropdownNode, X as NavigationNode, Y as NavNode, Z as TabsNode, _ as BreadcrumbNode, $ as DividerComponentNode, a0 as NodeType, a1 as WireframeDocument } from './types-CRocJqKS.js';
2
+ export { az as AlertVariant, ac as AlignValue, au as AvatarSize, aw as BadgeSize, av as BadgeVariant, a4 as BaseNode, aL as BreadcrumbItem, at as ButtonSize, as as ButtonVariant, ah as CommonProps, ad as DirectionValue, aE as DividerNode, ak as DrawerPosition, aD as DropdownItemNode, ae as FlexProps, af as GridProps, a9 as HeightValue, ax as IconSize, aq as InputType, ai as InteractiveProps, ab as JustifyValue, ay as ListItemNode, aG as NavBlockItem, aJ as NavChild, aI as NavDivider, aH as NavGroupNode, aF as NavItem, a2 as Position, ag as PositionProps, ar as SelectOption, aj as ShadowValue, aa as SizeProps, a3 as SourceLocation, a7 as SpacingProps, a6 as SpacingValue, aB as SpinnerSize, aK as TabNode, ao as TextAlign, am as TextSize, al as TextSizeToken, an as TextWeight, ap as TitleLevel, aA as ToastPosition, aC as TooltipPosition, a5 as ValueWithUnit, a8 as WidthValue } from './types-CRocJqKS.js';
3
3
  export { ExpectedToken, ParseError, ParseErrorInfo, ParseOptions, ParseResult, getErrors, isValid, parse, tryParse } from './parser.js';
4
4
  export { HtmlRenderer, IconData, IconElement, RenderContext, RenderOptions, RenderResult, SvgRenderOptions, SvgRenderResult, ThemeColors, ThemeConfig, createHtmlRenderer, darkTheme, defaultTheme, generateComponentStyles, generateStyles, getIconData, getTheme, lucideIcons, render, renderIconSvg, renderToHtml, renderToSvg } from './renderer.js';
5
5
 
package/dist/index.js CHANGED
@@ -8212,6 +8212,14 @@ ${children}
8212
8212
  }
8213
8213
 
8214
8214
  // src/renderer/html/renderers/container.ts
8215
+ function buildInteractiveAttrs(node) {
8216
+ return {
8217
+ "data-navigate": node.navigate,
8218
+ "data-opens": node.opens,
8219
+ "data-toggles": node.toggles,
8220
+ "data-action": node.action
8221
+ };
8222
+ }
8215
8223
  function renderCard(node, ctx) {
8216
8224
  const hasExplicitWidth = node.w !== void 0;
8217
8225
  const classes = ctx.buildClassString([
@@ -8222,10 +8230,12 @@ function renderCard(node, ctx) {
8222
8230
  ]);
8223
8231
  const styles = ctx.buildCommonStyles(node);
8224
8232
  const styleAttr = styles ? ` style="${styles}"` : "";
8233
+ const interactiveAttrs = buildInteractiveAttrs(node);
8234
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
8225
8235
  const title = node.title ? `<h3 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h3>
8226
8236
  ` : "";
8227
8237
  const children = ctx.renderChildren(node.children);
8228
- return `<div class="${classes}"${styleAttr}>
8238
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr}>
8229
8239
  ${title}${children}
8230
8240
  </div>`;
8231
8241
  }
@@ -8236,10 +8246,11 @@ function renderModal(node, ctx) {
8236
8246
  ]);
8237
8247
  const styles = ctx.buildCommonStyles(node);
8238
8248
  const styleAttr = styles ? ` style="${styles}"` : "";
8249
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
8239
8250
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
8240
8251
  ` : "";
8241
8252
  const children = ctx.renderChildren(node.children);
8242
- return `<div class="${ctx.prefix}-modal-backdrop">
8253
+ return `<div class="${ctx.prefix}-modal-backdrop"${idAttr}>
8243
8254
  <div class="${classes}"${styleAttr} role="dialog" aria-modal="true">
8244
8255
  ${title}${children}
8245
8256
  </div>
@@ -8254,10 +8265,11 @@ function renderDrawer(node, ctx) {
8254
8265
  ]);
8255
8266
  const styles = ctx.buildCommonStyles(node);
8256
8267
  const styleAttr = styles ? ` style="${styles}"` : "";
8268
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
8257
8269
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
8258
8270
  ` : "";
8259
8271
  const children = ctx.renderChildren(node.children);
8260
- return `<aside class="${classes}"${styleAttr}>
8272
+ return `<aside class="${classes}"${styleAttr}${idAttr}>
8261
8273
  ${title}${children}
8262
8274
  </aside>`;
8263
8275
  }
@@ -8314,7 +8326,12 @@ function renderLink(node, ctx) {
8314
8326
  const styleAttr = styles ? ` style="${styles}"` : "";
8315
8327
  const attrs = {
8316
8328
  class: classes,
8317
- href: node.href || "#"
8329
+ href: node.href || node.navigate || "#",
8330
+ // Interactive attributes
8331
+ "data-navigate": node.navigate,
8332
+ "data-opens": node.opens,
8333
+ "data-toggles": node.toggles,
8334
+ "data-action": node.action
8318
8335
  };
8319
8336
  if (node.external) {
8320
8337
  attrs.target = "_blank";
@@ -54742,7 +54759,12 @@ function renderButton(node, ctx) {
54742
54759
  const styleAttr = styles ? ` style="${styles}"` : "";
54743
54760
  const attrs = {
54744
54761
  class: classes,
54745
- disabled: node.disabled
54762
+ disabled: node.disabled,
54763
+ // Interactive attributes
54764
+ "data-navigate": node.navigate,
54765
+ "data-opens": node.opens,
54766
+ "data-toggles": node.toggles,
54767
+ "data-action": node.action
54746
54768
  };
54747
54769
  let icon = "";
54748
54770
  if (node.icon) {
@@ -54984,6 +55006,14 @@ ${slider}`;
54984
55006
  }
54985
55007
 
54986
55008
  // src/renderer/html/renderers/display.ts
55009
+ function buildInteractiveAttrs2(node) {
55010
+ return {
55011
+ "data-navigate": node.navigate,
55012
+ "data-opens": node.opens,
55013
+ "data-toggles": node.toggles,
55014
+ "data-action": node.action
55015
+ };
55016
+ }
54987
55017
  function renderImage(node, ctx) {
54988
55018
  const classes = ctx.buildClassString([
54989
55019
  `${ctx.prefix}-image`,
@@ -54995,14 +55025,17 @@ function renderImage(node, ctx) {
54995
55025
  const attrs = {
54996
55026
  class: classes,
54997
55027
  src: node.src,
54998
- alt: node.alt || "Image"
55028
+ alt: node.alt || "Image",
55029
+ ...buildInteractiveAttrs2(node)
54999
55030
  };
55000
55031
  const imgStyleAttr = styles ? `; ${styles}` : "";
55001
55032
  return `<img${ctx.buildAttrsString(attrs)}${imgStyleAttr ? ` style="${imgStyleAttr.slice(2)}"` : ""} />`;
55002
55033
  }
55003
55034
  const label = node.alt || "Image";
55004
55035
  const icon = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
55005
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
55036
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55037
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55038
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
55006
55039
  }
55007
55040
  function renderPlaceholder(node, ctx) {
55008
55041
  const classes = ctx.buildClassString([
@@ -55034,9 +55067,13 @@ function renderAvatar(node, ctx) {
55034
55067
  const combinedStyles = baseStyles && sizeStyle ? `${baseStyles}; ${sizeStyle}` : baseStyles || sizeStyle;
55035
55068
  const styleAttr = combinedStyles ? ` style="${combinedStyles}"` : "";
55036
55069
  const initials = node.name ? node.name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
55037
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
55070
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55071
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55072
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
55038
55073
  }
55039
55074
  function renderBadge(node, ctx) {
55075
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55076
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55040
55077
  if (node.icon) {
55041
55078
  const iconData = getIconData(node.icon);
55042
55079
  const classes2 = ctx.buildClassString([
@@ -55049,9 +55086,9 @@ function renderBadge(node, ctx) {
55049
55086
  const styleAttr2 = styles2 ? ` style="${styles2}"` : "";
55050
55087
  if (iconData) {
55051
55088
  const svg = renderIconSvg(iconData, 24, 2, `${ctx.prefix}-icon`);
55052
- return `<span class="${classes2}"${styleAttr2} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
55089
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
55053
55090
  }
55054
- return `<span class="${classes2}"${styleAttr2} aria-label="unknown icon">?</span>`;
55091
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="unknown icon">?</span>`;
55055
55092
  }
55056
55093
  const isDot = !node.content || node.content.trim() === "";
55057
55094
  const classes = ctx.buildClassString([
@@ -55063,10 +55100,12 @@ function renderBadge(node, ctx) {
55063
55100
  ]);
55064
55101
  const styles = ctx.buildCommonStyles(node);
55065
55102
  const styleAttr = styles ? ` style="${styles}"` : "";
55066
- return `<span class="${classes}"${styleAttr}>${ctx.escapeHtml(node.content)}</span>`;
55103
+ return `<span class="${classes}"${styleAttr}${interactiveAttrStr}>${ctx.escapeHtml(node.content)}</span>`;
55067
55104
  }
55068
55105
  function renderIcon(node, ctx) {
55069
55106
  const iconData = getIconData(node.name);
55107
+ const interactiveAttrs = buildInteractiveAttrs2(node);
55108
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55070
55109
  const sizeResolved = resolveSizeValue(node.size, "icon", ctx.prefix);
55071
55110
  const wrapperClasses = ctx.buildClassString([
55072
55111
  `${ctx.prefix}-icon-wrapper`,
@@ -55082,7 +55121,7 @@ function renderIcon(node, ctx) {
55082
55121
  const svgStyleAttr = sizeResolved.style ? ` style="${sizeResolved.style}"` : "";
55083
55122
  const svg = renderIconSvg(iconData, 24, 2, iconClasses, svgStyleAttr);
55084
55123
  const wrapperStyleAttr2 = baseStyles ? ` style="${baseStyles}"` : "";
55085
- return `<span class="${wrapperClasses}"${wrapperStyleAttr2} aria-hidden="true">${svg}</span>`;
55124
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr2}${interactiveAttrStr} aria-hidden="true">${svg}</span>`;
55086
55125
  }
55087
55126
  const size = sizeResolved.style?.match(/(\d+)px/)?.[1] || "24";
55088
55127
  const sizeNum = parseInt(size, 10);
@@ -55091,7 +55130,7 @@ function renderIcon(node, ctx) {
55091
55130
  <text x="12" y="16" text-anchor="middle" font-size="10" fill="currentColor" opacity="0.7">?</text>
55092
55131
  </svg>`;
55093
55132
  const wrapperStyleAttr = baseStyles ? ` style="${baseStyles}"` : "";
55094
- return `<span class="${wrapperClasses}"${wrapperStyleAttr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
55133
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr}${interactiveAttrStr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
55095
55134
  }
55096
55135
 
55097
55136
  // src/renderer/html/renderers/overlay.ts
@@ -55142,7 +55181,20 @@ function renderDropdown(node, ctx) {
55142
55181
  dropdownItem.danger ? `${ctx.prefix}-dropdown-item-danger` : void 0,
55143
55182
  dropdownItem.disabled ? `${ctx.prefix}-dropdown-item-disabled` : void 0
55144
55183
  ]);
55145
- return `<button class="${itemClasses}"${dropdownItem.disabled ? ' disabled="disabled"' : ""}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
55184
+ const interactiveAttrs = {
55185
+ "data-navigate": dropdownItem.navigate,
55186
+ "data-opens": dropdownItem.opens,
55187
+ "data-toggles": dropdownItem.toggles,
55188
+ "data-action": dropdownItem.action
55189
+ };
55190
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
55191
+ const hrefAttr = dropdownItem.href ? ` href="${ctx.escapeHtml(dropdownItem.href)}"` : "";
55192
+ const disabledAttr = dropdownItem.disabled ? ' disabled="disabled"' : "";
55193
+ if (dropdownItem.href || dropdownItem.navigate) {
55194
+ const href = dropdownItem.href || dropdownItem.navigate || "#";
55195
+ return `<a class="${itemClasses}" href="${ctx.escapeHtml(href)}"${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</a>`;
55196
+ }
55197
+ return `<button class="${itemClasses}"${disabledAttr}${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
55146
55198
  }).join("\n");
55147
55199
  return `<div class="${classes}"${styleAttr}>
55148
55200
  ${items}
package/dist/parser.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a3 as SourceLocation, a1 as WireframeDocument } from './types-lcJzPcR0.cjs';
1
+ import { a3 as SourceLocation, a1 as WireframeDocument } from './types-CRocJqKS.cjs';
2
2
 
3
3
  /**
4
4
  * Parser module for wireweave
package/dist/parser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a3 as SourceLocation, a1 as WireframeDocument } from './types-lcJzPcR0.js';
1
+ import { a3 as SourceLocation, a1 as WireframeDocument } from './types-CRocJqKS.js';
2
2
 
3
3
  /**
4
4
  * Parser module for wireweave
package/dist/renderer.cjs CHANGED
@@ -2003,6 +2003,14 @@ ${children}
2003
2003
  }
2004
2004
 
2005
2005
  // src/renderer/html/renderers/container.ts
2006
+ function buildInteractiveAttrs(node) {
2007
+ return {
2008
+ "data-navigate": node.navigate,
2009
+ "data-opens": node.opens,
2010
+ "data-toggles": node.toggles,
2011
+ "data-action": node.action
2012
+ };
2013
+ }
2006
2014
  function renderCard(node, ctx) {
2007
2015
  const hasExplicitWidth = node.w !== void 0;
2008
2016
  const classes = ctx.buildClassString([
@@ -2013,10 +2021,12 @@ function renderCard(node, ctx) {
2013
2021
  ]);
2014
2022
  const styles = ctx.buildCommonStyles(node);
2015
2023
  const styleAttr = styles ? ` style="${styles}"` : "";
2024
+ const interactiveAttrs = buildInteractiveAttrs(node);
2025
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
2016
2026
  const title = node.title ? `<h3 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h3>
2017
2027
  ` : "";
2018
2028
  const children = ctx.renderChildren(node.children);
2019
- return `<div class="${classes}"${styleAttr}>
2029
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr}>
2020
2030
  ${title}${children}
2021
2031
  </div>`;
2022
2032
  }
@@ -2027,10 +2037,11 @@ function renderModal(node, ctx) {
2027
2037
  ]);
2028
2038
  const styles = ctx.buildCommonStyles(node);
2029
2039
  const styleAttr = styles ? ` style="${styles}"` : "";
2040
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
2030
2041
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
2031
2042
  ` : "";
2032
2043
  const children = ctx.renderChildren(node.children);
2033
- return `<div class="${ctx.prefix}-modal-backdrop">
2044
+ return `<div class="${ctx.prefix}-modal-backdrop"${idAttr}>
2034
2045
  <div class="${classes}"${styleAttr} role="dialog" aria-modal="true">
2035
2046
  ${title}${children}
2036
2047
  </div>
@@ -2045,10 +2056,11 @@ function renderDrawer(node, ctx) {
2045
2056
  ]);
2046
2057
  const styles = ctx.buildCommonStyles(node);
2047
2058
  const styleAttr = styles ? ` style="${styles}"` : "";
2059
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
2048
2060
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
2049
2061
  ` : "";
2050
2062
  const children = ctx.renderChildren(node.children);
2051
- return `<aside class="${classes}"${styleAttr}>
2063
+ return `<aside class="${classes}"${styleAttr}${idAttr}>
2052
2064
  ${title}${children}
2053
2065
  </aside>`;
2054
2066
  }
@@ -2105,7 +2117,12 @@ function renderLink(node, ctx) {
2105
2117
  const styleAttr = styles ? ` style="${styles}"` : "";
2106
2118
  const attrs = {
2107
2119
  class: classes,
2108
- href: node.href || "#"
2120
+ href: node.href || node.navigate || "#",
2121
+ // Interactive attributes
2122
+ "data-navigate": node.navigate,
2123
+ "data-opens": node.opens,
2124
+ "data-toggles": node.toggles,
2125
+ "data-action": node.action
2109
2126
  };
2110
2127
  if (node.external) {
2111
2128
  attrs.target = "_blank";
@@ -48533,7 +48550,12 @@ function renderButton(node, ctx) {
48533
48550
  const styleAttr = styles ? ` style="${styles}"` : "";
48534
48551
  const attrs = {
48535
48552
  class: classes,
48536
- disabled: node.disabled
48553
+ disabled: node.disabled,
48554
+ // Interactive attributes
48555
+ "data-navigate": node.navigate,
48556
+ "data-opens": node.opens,
48557
+ "data-toggles": node.toggles,
48558
+ "data-action": node.action
48537
48559
  };
48538
48560
  let icon = "";
48539
48561
  if (node.icon) {
@@ -48775,6 +48797,14 @@ ${slider}`;
48775
48797
  }
48776
48798
 
48777
48799
  // src/renderer/html/renderers/display.ts
48800
+ function buildInteractiveAttrs2(node) {
48801
+ return {
48802
+ "data-navigate": node.navigate,
48803
+ "data-opens": node.opens,
48804
+ "data-toggles": node.toggles,
48805
+ "data-action": node.action
48806
+ };
48807
+ }
48778
48808
  function renderImage(node, ctx) {
48779
48809
  const classes = ctx.buildClassString([
48780
48810
  `${ctx.prefix}-image`,
@@ -48786,14 +48816,17 @@ function renderImage(node, ctx) {
48786
48816
  const attrs = {
48787
48817
  class: classes,
48788
48818
  src: node.src,
48789
- alt: node.alt || "Image"
48819
+ alt: node.alt || "Image",
48820
+ ...buildInteractiveAttrs2(node)
48790
48821
  };
48791
48822
  const imgStyleAttr = styles ? `; ${styles}` : "";
48792
48823
  return `<img${ctx.buildAttrsString(attrs)}${imgStyleAttr ? ` style="${imgStyleAttr.slice(2)}"` : ""} />`;
48793
48824
  }
48794
48825
  const label = node.alt || "Image";
48795
48826
  const icon = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
48796
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
48827
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48828
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48829
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
48797
48830
  }
48798
48831
  function renderPlaceholder(node, ctx) {
48799
48832
  const classes = ctx.buildClassString([
@@ -48825,9 +48858,13 @@ function renderAvatar(node, ctx) {
48825
48858
  const combinedStyles = baseStyles && sizeStyle ? `${baseStyles}; ${sizeStyle}` : baseStyles || sizeStyle;
48826
48859
  const styleAttr = combinedStyles ? ` style="${combinedStyles}"` : "";
48827
48860
  const initials = node.name ? node.name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
48828
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
48861
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48862
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48863
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
48829
48864
  }
48830
48865
  function renderBadge(node, ctx) {
48866
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48867
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48831
48868
  if (node.icon) {
48832
48869
  const iconData = getIconData(node.icon);
48833
48870
  const classes2 = ctx.buildClassString([
@@ -48840,9 +48877,9 @@ function renderBadge(node, ctx) {
48840
48877
  const styleAttr2 = styles2 ? ` style="${styles2}"` : "";
48841
48878
  if (iconData) {
48842
48879
  const svg = renderIconSvg(iconData, 24, 2, `${ctx.prefix}-icon`);
48843
- return `<span class="${classes2}"${styleAttr2} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
48880
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
48844
48881
  }
48845
- return `<span class="${classes2}"${styleAttr2} aria-label="unknown icon">?</span>`;
48882
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="unknown icon">?</span>`;
48846
48883
  }
48847
48884
  const isDot = !node.content || node.content.trim() === "";
48848
48885
  const classes = ctx.buildClassString([
@@ -48854,10 +48891,12 @@ function renderBadge(node, ctx) {
48854
48891
  ]);
48855
48892
  const styles = ctx.buildCommonStyles(node);
48856
48893
  const styleAttr = styles ? ` style="${styles}"` : "";
48857
- return `<span class="${classes}"${styleAttr}>${ctx.escapeHtml(node.content)}</span>`;
48894
+ return `<span class="${classes}"${styleAttr}${interactiveAttrStr}>${ctx.escapeHtml(node.content)}</span>`;
48858
48895
  }
48859
48896
  function renderIcon(node, ctx) {
48860
48897
  const iconData = getIconData(node.name);
48898
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48899
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48861
48900
  const sizeResolved = resolveSizeValue(node.size, "icon", ctx.prefix);
48862
48901
  const wrapperClasses = ctx.buildClassString([
48863
48902
  `${ctx.prefix}-icon-wrapper`,
@@ -48873,7 +48912,7 @@ function renderIcon(node, ctx) {
48873
48912
  const svgStyleAttr = sizeResolved.style ? ` style="${sizeResolved.style}"` : "";
48874
48913
  const svg = renderIconSvg(iconData, 24, 2, iconClasses, svgStyleAttr);
48875
48914
  const wrapperStyleAttr2 = baseStyles ? ` style="${baseStyles}"` : "";
48876
- return `<span class="${wrapperClasses}"${wrapperStyleAttr2} aria-hidden="true">${svg}</span>`;
48915
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr2}${interactiveAttrStr} aria-hidden="true">${svg}</span>`;
48877
48916
  }
48878
48917
  const size = sizeResolved.style?.match(/(\d+)px/)?.[1] || "24";
48879
48918
  const sizeNum = parseInt(size, 10);
@@ -48882,7 +48921,7 @@ function renderIcon(node, ctx) {
48882
48921
  <text x="12" y="16" text-anchor="middle" font-size="10" fill="currentColor" opacity="0.7">?</text>
48883
48922
  </svg>`;
48884
48923
  const wrapperStyleAttr = baseStyles ? ` style="${baseStyles}"` : "";
48885
- return `<span class="${wrapperClasses}"${wrapperStyleAttr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
48924
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr}${interactiveAttrStr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
48886
48925
  }
48887
48926
 
48888
48927
  // src/renderer/html/renderers/overlay.ts
@@ -48933,7 +48972,20 @@ function renderDropdown(node, ctx) {
48933
48972
  dropdownItem.danger ? `${ctx.prefix}-dropdown-item-danger` : void 0,
48934
48973
  dropdownItem.disabled ? `${ctx.prefix}-dropdown-item-disabled` : void 0
48935
48974
  ]);
48936
- return `<button class="${itemClasses}"${dropdownItem.disabled ? ' disabled="disabled"' : ""}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
48975
+ const interactiveAttrs = {
48976
+ "data-navigate": dropdownItem.navigate,
48977
+ "data-opens": dropdownItem.opens,
48978
+ "data-toggles": dropdownItem.toggles,
48979
+ "data-action": dropdownItem.action
48980
+ };
48981
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48982
+ const hrefAttr = dropdownItem.href ? ` href="${ctx.escapeHtml(dropdownItem.href)}"` : "";
48983
+ const disabledAttr = dropdownItem.disabled ? ' disabled="disabled"' : "";
48984
+ if (dropdownItem.href || dropdownItem.navigate) {
48985
+ const href = dropdownItem.href || dropdownItem.navigate || "#";
48986
+ return `<a class="${itemClasses}" href="${ctx.escapeHtml(href)}"${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</a>`;
48987
+ }
48988
+ return `<button class="${itemClasses}"${disabledAttr}${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
48937
48989
  }).join("\n");
48938
48990
  return `<div class="${classes}"${styleAttr}>
48939
48991
  ${items}
@@ -1,4 +1,4 @@
1
- import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-lcJzPcR0.cjs';
1
+ import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-CRocJqKS.cjs';
2
2
 
3
3
  /**
4
4
  * Renderer type definitions for wireweave
@@ -1,4 +1,4 @@
1
- import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-lcJzPcR0.js';
1
+ import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-CRocJqKS.js';
2
2
 
3
3
  /**
4
4
  * Renderer type definitions for wireweave
package/dist/renderer.js CHANGED
@@ -1965,6 +1965,14 @@ ${children}
1965
1965
  }
1966
1966
 
1967
1967
  // src/renderer/html/renderers/container.ts
1968
+ function buildInteractiveAttrs(node) {
1969
+ return {
1970
+ "data-navigate": node.navigate,
1971
+ "data-opens": node.opens,
1972
+ "data-toggles": node.toggles,
1973
+ "data-action": node.action
1974
+ };
1975
+ }
1968
1976
  function renderCard(node, ctx) {
1969
1977
  const hasExplicitWidth = node.w !== void 0;
1970
1978
  const classes = ctx.buildClassString([
@@ -1975,10 +1983,12 @@ function renderCard(node, ctx) {
1975
1983
  ]);
1976
1984
  const styles = ctx.buildCommonStyles(node);
1977
1985
  const styleAttr = styles ? ` style="${styles}"` : "";
1986
+ const interactiveAttrs = buildInteractiveAttrs(node);
1987
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
1978
1988
  const title = node.title ? `<h3 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h3>
1979
1989
  ` : "";
1980
1990
  const children = ctx.renderChildren(node.children);
1981
- return `<div class="${classes}"${styleAttr}>
1991
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr}>
1982
1992
  ${title}${children}
1983
1993
  </div>`;
1984
1994
  }
@@ -1989,10 +1999,11 @@ function renderModal(node, ctx) {
1989
1999
  ]);
1990
2000
  const styles = ctx.buildCommonStyles(node);
1991
2001
  const styleAttr = styles ? ` style="${styles}"` : "";
2002
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
1992
2003
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
1993
2004
  ` : "";
1994
2005
  const children = ctx.renderChildren(node.children);
1995
- return `<div class="${ctx.prefix}-modal-backdrop">
2006
+ return `<div class="${ctx.prefix}-modal-backdrop"${idAttr}>
1996
2007
  <div class="${classes}"${styleAttr} role="dialog" aria-modal="true">
1997
2008
  ${title}${children}
1998
2009
  </div>
@@ -2007,10 +2018,11 @@ function renderDrawer(node, ctx) {
2007
2018
  ]);
2008
2019
  const styles = ctx.buildCommonStyles(node);
2009
2020
  const styleAttr = styles ? ` style="${styles}"` : "";
2021
+ const idAttr = node.id ? ` id="${ctx.escapeHtml(node.id)}"` : "";
2010
2022
  const title = node.title ? `<h2 class="${ctx.prefix}-title">${ctx.escapeHtml(node.title)}</h2>
2011
2023
  ` : "";
2012
2024
  const children = ctx.renderChildren(node.children);
2013
- return `<aside class="${classes}"${styleAttr}>
2025
+ return `<aside class="${classes}"${styleAttr}${idAttr}>
2014
2026
  ${title}${children}
2015
2027
  </aside>`;
2016
2028
  }
@@ -2067,7 +2079,12 @@ function renderLink(node, ctx) {
2067
2079
  const styleAttr = styles ? ` style="${styles}"` : "";
2068
2080
  const attrs = {
2069
2081
  class: classes,
2070
- href: node.href || "#"
2082
+ href: node.href || node.navigate || "#",
2083
+ // Interactive attributes
2084
+ "data-navigate": node.navigate,
2085
+ "data-opens": node.opens,
2086
+ "data-toggles": node.toggles,
2087
+ "data-action": node.action
2071
2088
  };
2072
2089
  if (node.external) {
2073
2090
  attrs.target = "_blank";
@@ -48495,7 +48512,12 @@ function renderButton(node, ctx) {
48495
48512
  const styleAttr = styles ? ` style="${styles}"` : "";
48496
48513
  const attrs = {
48497
48514
  class: classes,
48498
- disabled: node.disabled
48515
+ disabled: node.disabled,
48516
+ // Interactive attributes
48517
+ "data-navigate": node.navigate,
48518
+ "data-opens": node.opens,
48519
+ "data-toggles": node.toggles,
48520
+ "data-action": node.action
48499
48521
  };
48500
48522
  let icon = "";
48501
48523
  if (node.icon) {
@@ -48737,6 +48759,14 @@ ${slider}`;
48737
48759
  }
48738
48760
 
48739
48761
  // src/renderer/html/renderers/display.ts
48762
+ function buildInteractiveAttrs2(node) {
48763
+ return {
48764
+ "data-navigate": node.navigate,
48765
+ "data-opens": node.opens,
48766
+ "data-toggles": node.toggles,
48767
+ "data-action": node.action
48768
+ };
48769
+ }
48740
48770
  function renderImage(node, ctx) {
48741
48771
  const classes = ctx.buildClassString([
48742
48772
  `${ctx.prefix}-image`,
@@ -48748,14 +48778,17 @@ function renderImage(node, ctx) {
48748
48778
  const attrs = {
48749
48779
  class: classes,
48750
48780
  src: node.src,
48751
- alt: node.alt || "Image"
48781
+ alt: node.alt || "Image",
48782
+ ...buildInteractiveAttrs2(node)
48752
48783
  };
48753
48784
  const imgStyleAttr = styles ? `; ${styles}` : "";
48754
48785
  return `<img${ctx.buildAttrsString(attrs)}${imgStyleAttr ? ` style="${imgStyleAttr.slice(2)}"` : ""} />`;
48755
48786
  }
48756
48787
  const label = node.alt || "Image";
48757
48788
  const icon = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
48758
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
48789
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48790
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48791
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(label)}">${icon}<span>${ctx.escapeHtml(label)}</span></div>`;
48759
48792
  }
48760
48793
  function renderPlaceholder(node, ctx) {
48761
48794
  const classes = ctx.buildClassString([
@@ -48787,9 +48820,13 @@ function renderAvatar(node, ctx) {
48787
48820
  const combinedStyles = baseStyles && sizeStyle ? `${baseStyles}; ${sizeStyle}` : baseStyles || sizeStyle;
48788
48821
  const styleAttr = combinedStyles ? ` style="${combinedStyles}"` : "";
48789
48822
  const initials = node.name ? node.name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : "?";
48790
- return `<div class="${classes}"${styleAttr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
48823
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48824
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48825
+ return `<div class="${classes}"${styleAttr}${interactiveAttrStr} role="img" aria-label="${ctx.escapeHtml(node.name || "Avatar")}">${initials}</div>`;
48791
48826
  }
48792
48827
  function renderBadge(node, ctx) {
48828
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48829
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48793
48830
  if (node.icon) {
48794
48831
  const iconData = getIconData(node.icon);
48795
48832
  const classes2 = ctx.buildClassString([
@@ -48802,9 +48839,9 @@ function renderBadge(node, ctx) {
48802
48839
  const styleAttr2 = styles2 ? ` style="${styles2}"` : "";
48803
48840
  if (iconData) {
48804
48841
  const svg = renderIconSvg(iconData, 24, 2, `${ctx.prefix}-icon`);
48805
- return `<span class="${classes2}"${styleAttr2} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
48842
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="${ctx.escapeHtml(node.icon)}">${svg}</span>`;
48806
48843
  }
48807
- return `<span class="${classes2}"${styleAttr2} aria-label="unknown icon">?</span>`;
48844
+ return `<span class="${classes2}"${styleAttr2}${interactiveAttrStr} aria-label="unknown icon">?</span>`;
48808
48845
  }
48809
48846
  const isDot = !node.content || node.content.trim() === "";
48810
48847
  const classes = ctx.buildClassString([
@@ -48816,10 +48853,12 @@ function renderBadge(node, ctx) {
48816
48853
  ]);
48817
48854
  const styles = ctx.buildCommonStyles(node);
48818
48855
  const styleAttr = styles ? ` style="${styles}"` : "";
48819
- return `<span class="${classes}"${styleAttr}>${ctx.escapeHtml(node.content)}</span>`;
48856
+ return `<span class="${classes}"${styleAttr}${interactiveAttrStr}>${ctx.escapeHtml(node.content)}</span>`;
48820
48857
  }
48821
48858
  function renderIcon(node, ctx) {
48822
48859
  const iconData = getIconData(node.name);
48860
+ const interactiveAttrs = buildInteractiveAttrs2(node);
48861
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48823
48862
  const sizeResolved = resolveSizeValue(node.size, "icon", ctx.prefix);
48824
48863
  const wrapperClasses = ctx.buildClassString([
48825
48864
  `${ctx.prefix}-icon-wrapper`,
@@ -48835,7 +48874,7 @@ function renderIcon(node, ctx) {
48835
48874
  const svgStyleAttr = sizeResolved.style ? ` style="${sizeResolved.style}"` : "";
48836
48875
  const svg = renderIconSvg(iconData, 24, 2, iconClasses, svgStyleAttr);
48837
48876
  const wrapperStyleAttr2 = baseStyles ? ` style="${baseStyles}"` : "";
48838
- return `<span class="${wrapperClasses}"${wrapperStyleAttr2} aria-hidden="true">${svg}</span>`;
48877
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr2}${interactiveAttrStr} aria-hidden="true">${svg}</span>`;
48839
48878
  }
48840
48879
  const size = sizeResolved.style?.match(/(\d+)px/)?.[1] || "24";
48841
48880
  const sizeNum = parseInt(size, 10);
@@ -48844,7 +48883,7 @@ function renderIcon(node, ctx) {
48844
48883
  <text x="12" y="16" text-anchor="middle" font-size="10" fill="currentColor" opacity="0.7">?</text>
48845
48884
  </svg>`;
48846
48885
  const wrapperStyleAttr = baseStyles ? ` style="${baseStyles}"` : "";
48847
- return `<span class="${wrapperClasses}"${wrapperStyleAttr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
48886
+ return `<span class="${wrapperClasses}"${wrapperStyleAttr}${interactiveAttrStr} aria-hidden="true" title="Unknown icon: ${ctx.escapeHtml(node.name)}">${placeholderSvg}</span>`;
48848
48887
  }
48849
48888
 
48850
48889
  // src/renderer/html/renderers/overlay.ts
@@ -48895,7 +48934,20 @@ function renderDropdown(node, ctx) {
48895
48934
  dropdownItem.danger ? `${ctx.prefix}-dropdown-item-danger` : void 0,
48896
48935
  dropdownItem.disabled ? `${ctx.prefix}-dropdown-item-disabled` : void 0
48897
48936
  ]);
48898
- return `<button class="${itemClasses}"${dropdownItem.disabled ? ' disabled="disabled"' : ""}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
48937
+ const interactiveAttrs = {
48938
+ "data-navigate": dropdownItem.navigate,
48939
+ "data-opens": dropdownItem.opens,
48940
+ "data-toggles": dropdownItem.toggles,
48941
+ "data-action": dropdownItem.action
48942
+ };
48943
+ const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
48944
+ const hrefAttr = dropdownItem.href ? ` href="${ctx.escapeHtml(dropdownItem.href)}"` : "";
48945
+ const disabledAttr = dropdownItem.disabled ? ' disabled="disabled"' : "";
48946
+ if (dropdownItem.href || dropdownItem.navigate) {
48947
+ const href = dropdownItem.href || dropdownItem.navigate || "#";
48948
+ return `<a class="${itemClasses}" href="${ctx.escapeHtml(href)}"${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</a>`;
48949
+ }
48950
+ return `<button class="${itemClasses}"${disabledAttr}${interactiveAttrStr}>${ctx.escapeHtml(dropdownItem.label)}</button>`;
48899
48951
  }).join("\n");
48900
48952
  return `<div class="${classes}"${styleAttr}>
48901
48953
  ${items}
@@ -87,6 +87,20 @@ interface PositionProps {
87
87
  }
88
88
  interface CommonProps extends SpacingProps, SizeProps, FlexProps, GridProps, PositionProps {
89
89
  }
90
+ /**
91
+ * Interactive properties for components that can trigger actions.
92
+ * Used for buttons, links, avatars, icons, and other clickable elements.
93
+ */
94
+ interface InteractiveProps {
95
+ /** Navigate to another page or URL */
96
+ navigate?: string;
97
+ /** Opens a modal, drawer, or other overlay element by id */
98
+ opens?: string;
99
+ /** Toggles visibility or state of an element by id */
100
+ toggles?: string;
101
+ /** Custom action identifier (e.g., "submit", "logout", "delete") */
102
+ action?: string;
103
+ }
90
104
  interface WireframeDocument extends BaseNode {
91
105
  type: 'Document';
92
106
  children: PageNode[];
@@ -145,7 +159,7 @@ interface ColNode extends BaseNode, CommonProps {
145
159
  children: AnyNode[];
146
160
  }
147
161
  type ShadowValue = 'none' | 'sm' | 'md' | 'lg' | 'xl';
148
- interface CardNode extends BaseNode, CommonProps {
162
+ interface CardNode extends BaseNode, CommonProps, InteractiveProps {
149
163
  type: 'Card';
150
164
  title?: string | null;
151
165
  shadow?: ShadowValue;
@@ -155,12 +169,16 @@ interface CardNode extends BaseNode, CommonProps {
155
169
  interface ModalNode extends BaseNode, CommonProps {
156
170
  type: 'Modal';
157
171
  title?: string | null;
172
+ /** Unique identifier for targeting with opens/toggles */
173
+ id?: string;
158
174
  children: AnyNode[];
159
175
  }
160
176
  type DrawerPosition = 'left' | 'right' | 'top' | 'bottom';
161
177
  interface DrawerNode extends BaseNode, CommonProps {
162
178
  type: 'Drawer';
163
179
  title?: string | null;
180
+ /** Unique identifier for targeting with opens/toggles */
181
+ id?: string;
164
182
  position?: DrawerPosition;
165
183
  children: AnyNode[];
166
184
  }
@@ -189,7 +207,7 @@ interface TitleNode extends BaseNode, Omit<CommonProps, 'align'> {
189
207
  size?: TextSize;
190
208
  align?: TextAlign;
191
209
  }
192
- interface LinkNode extends BaseNode, CommonProps {
210
+ interface LinkNode extends BaseNode, CommonProps, InteractiveProps {
193
211
  type: 'Link';
194
212
  content: string;
195
213
  href?: string;
@@ -259,7 +277,7 @@ interface SliderNode extends BaseNode, CommonProps {
259
277
  }
260
278
  type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
261
279
  type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
262
- interface ButtonNode extends BaseNode, CommonProps {
280
+ interface ButtonNode extends BaseNode, CommonProps, InteractiveProps {
263
281
  type: 'Button';
264
282
  content: string;
265
283
  primary?: boolean;
@@ -272,7 +290,7 @@ interface ButtonNode extends BaseNode, CommonProps {
272
290
  disabled?: boolean;
273
291
  loading?: boolean;
274
292
  }
275
- interface ImageNode extends BaseNode, CommonProps {
293
+ interface ImageNode extends BaseNode, CommonProps, InteractiveProps {
276
294
  type: 'Image';
277
295
  src?: string | null;
278
296
  alt?: string;
@@ -283,7 +301,7 @@ interface PlaceholderNode extends BaseNode, CommonProps {
283
301
  children?: AnyNode[];
284
302
  }
285
303
  type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
286
- interface AvatarNode extends BaseNode, CommonProps {
304
+ interface AvatarNode extends BaseNode, CommonProps, InteractiveProps {
287
305
  type: 'Avatar';
288
306
  name?: string | null;
289
307
  src?: boolean;
@@ -291,7 +309,7 @@ interface AvatarNode extends BaseNode, CommonProps {
291
309
  }
292
310
  type BadgeVariant = 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
293
311
  type BadgeSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
294
- interface BadgeNode extends BaseNode, CommonProps {
312
+ interface BadgeNode extends BaseNode, CommonProps, InteractiveProps {
295
313
  type: 'Badge';
296
314
  content: string;
297
315
  variant?: BadgeVariant;
@@ -300,7 +318,7 @@ interface BadgeNode extends BaseNode, CommonProps {
300
318
  size?: BadgeSize;
301
319
  }
302
320
  type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
303
- interface IconNode extends BaseNode, CommonProps {
321
+ interface IconNode extends BaseNode, CommonProps, InteractiveProps {
304
322
  type: 'Icon';
305
323
  name: string;
306
324
  size?: IconSize | number;
@@ -365,9 +383,10 @@ interface PopoverNode extends BaseNode, CommonProps {
365
383
  title?: string | null;
366
384
  children: AnyNode[];
367
385
  }
368
- interface DropdownItemNode {
386
+ interface DropdownItemNode extends InteractiveProps {
369
387
  label: string;
370
388
  icon?: string;
389
+ href?: string;
371
390
  danger?: boolean;
372
391
  disabled?: boolean;
373
392
  }
@@ -379,7 +398,7 @@ interface DropdownNode extends BaseNode, CommonProps {
379
398
  items: (DropdownItemNode | DividerNode)[];
380
399
  }
381
400
  /** Nav item for array syntax: nav ["a", "b"] */
382
- interface NavItem {
401
+ interface NavItem extends InteractiveProps {
383
402
  label: string;
384
403
  icon?: string;
385
404
  href?: string;
@@ -387,7 +406,7 @@ interface NavItem {
387
406
  disabled?: boolean;
388
407
  }
389
408
  /** Nav item for block syntax: item "label" icon="x" active */
390
- interface NavBlockItem {
409
+ interface NavBlockItem extends InteractiveProps {
391
410
  type: 'item';
392
411
  label: string;
393
412
  icon?: string;
@@ -428,7 +447,7 @@ interface TabsNode extends BaseNode, CommonProps {
428
447
  active?: number;
429
448
  children: TabNode[];
430
449
  }
431
- interface BreadcrumbItem {
450
+ interface BreadcrumbItem extends InteractiveProps {
432
451
  label: string;
433
452
  href?: string;
434
453
  }
@@ -454,4 +473,4 @@ type LeafNode = TextContentNode | InputComponentNode | ButtonNode | DisplayNode
454
473
  type AnyNode = ContainerNode | LeafNode;
455
474
  type NodeType = 'Document' | 'Page' | 'Header' | 'Main' | 'Footer' | 'Sidebar' | 'Section' | 'Row' | 'Col' | 'Card' | 'Modal' | 'Drawer' | 'Accordion' | 'Text' | 'Title' | 'Link' | 'Input' | 'Textarea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'Button' | 'Image' | 'Placeholder' | 'Avatar' | 'Badge' | 'Icon' | 'Table' | 'List' | 'Alert' | 'Toast' | 'Progress' | 'Spinner' | 'Tooltip' | 'Popover' | 'Dropdown' | 'Nav' | 'Tabs' | 'Breadcrumb' | 'Divider';
456
475
 
457
- export type { DividerComponentNode as $, AnyNode as A, ButtonNode as B, ContainerNode as C, DrawerNode as D, FeedbackNode as E, FooterNode as F, GridNode as G, HeaderNode as H, InputComponentNode as I, AlertNode as J, ToastNode as K, LeafNode as L, MainNode as M, ProgressNode as N, SpinnerNode as O, PageNode as P, OverlayNode as Q, RowNode as R, SidebarNode as S, TextContentNode as T, TooltipNode as U, PopoverNode as V, DropdownNode as W, NavigationNode as X, NavNode as Y, TabsNode as Z, BreadcrumbNode as _, LayoutNode as a, NodeType as a0, WireframeDocument as a1, Position as a2, SourceLocation as a3, BaseNode as a4, ValueWithUnit as a5, SpacingValue as a6, SpacingProps as a7, WidthValue as a8, HeightValue as a9, SpinnerSize as aA, TooltipPosition as aB, DropdownItemNode as aC, DividerNode as aD, NavItem as aE, NavBlockItem as aF, NavGroupNode as aG, NavDivider as aH, NavChild as aI, TabNode as aJ, BreadcrumbItem as aK, SizeProps as aa, JustifyValue as ab, AlignValue as ac, DirectionValue as ad, FlexProps as ae, GridProps as af, PositionProps as ag, CommonProps as ah, ShadowValue as ai, DrawerPosition as aj, TextSizeToken as ak, TextSize as al, TextWeight as am, TextAlign as an, TitleLevel as ao, InputType as ap, SelectOption as aq, ButtonVariant as ar, ButtonSize as as, AvatarSize as at, BadgeVariant as au, BadgeSize as av, IconSize as aw, ListItemNode as ax, AlertVariant as ay, ToastPosition as az, SectionNode as b, ColNode as c, ContainerComponentNode as d, CardNode as e, ModalNode as f, AccordionNode as g, TextNode as h, TitleNode as i, LinkNode as j, InputNode as k, TextareaNode as l, SelectNode as m, CheckboxNode as n, RadioNode as o, SwitchNode as p, SliderNode as q, DisplayNode as r, ImageNode as s, PlaceholderNode as t, AvatarNode as u, BadgeNode as v, IconNode as w, DataNode as x, TableNode as y, ListNode as z };
476
+ export type { DividerComponentNode as $, AnyNode as A, ButtonNode as B, ContainerNode as C, DrawerNode as D, FeedbackNode as E, FooterNode as F, GridNode as G, HeaderNode as H, InputComponentNode as I, AlertNode as J, ToastNode as K, LeafNode as L, MainNode as M, ProgressNode as N, SpinnerNode as O, PageNode as P, OverlayNode as Q, RowNode as R, SidebarNode as S, TextContentNode as T, TooltipNode as U, PopoverNode as V, DropdownNode as W, NavigationNode as X, NavNode as Y, TabsNode as Z, BreadcrumbNode as _, LayoutNode as a, NodeType as a0, WireframeDocument as a1, Position as a2, SourceLocation as a3, BaseNode as a4, ValueWithUnit as a5, SpacingValue as a6, SpacingProps as a7, WidthValue as a8, HeightValue as a9, ToastPosition as aA, SpinnerSize as aB, TooltipPosition as aC, DropdownItemNode as aD, DividerNode as aE, NavItem as aF, NavBlockItem as aG, NavGroupNode as aH, NavDivider as aI, NavChild as aJ, TabNode as aK, BreadcrumbItem as aL, SizeProps as aa, JustifyValue as ab, AlignValue as ac, DirectionValue as ad, FlexProps as ae, GridProps as af, PositionProps as ag, CommonProps as ah, InteractiveProps as ai, ShadowValue as aj, DrawerPosition as ak, TextSizeToken as al, TextSize as am, TextWeight as an, TextAlign as ao, TitleLevel as ap, InputType as aq, SelectOption as ar, ButtonVariant as as, ButtonSize as at, AvatarSize as au, BadgeVariant as av, BadgeSize as aw, IconSize as ax, ListItemNode as ay, AlertVariant as az, SectionNode as b, ColNode as c, ContainerComponentNode as d, CardNode as e, ModalNode as f, AccordionNode as g, TextNode as h, TitleNode as i, LinkNode as j, InputNode as k, TextareaNode as l, SelectNode as m, CheckboxNode as n, RadioNode as o, SwitchNode as p, SliderNode as q, DisplayNode as r, ImageNode as s, PlaceholderNode as t, AvatarNode as u, BadgeNode as v, IconNode as w, DataNode as x, TableNode as y, ListNode as z };
@@ -87,6 +87,20 @@ interface PositionProps {
87
87
  }
88
88
  interface CommonProps extends SpacingProps, SizeProps, FlexProps, GridProps, PositionProps {
89
89
  }
90
+ /**
91
+ * Interactive properties for components that can trigger actions.
92
+ * Used for buttons, links, avatars, icons, and other clickable elements.
93
+ */
94
+ interface InteractiveProps {
95
+ /** Navigate to another page or URL */
96
+ navigate?: string;
97
+ /** Opens a modal, drawer, or other overlay element by id */
98
+ opens?: string;
99
+ /** Toggles visibility or state of an element by id */
100
+ toggles?: string;
101
+ /** Custom action identifier (e.g., "submit", "logout", "delete") */
102
+ action?: string;
103
+ }
90
104
  interface WireframeDocument extends BaseNode {
91
105
  type: 'Document';
92
106
  children: PageNode[];
@@ -145,7 +159,7 @@ interface ColNode extends BaseNode, CommonProps {
145
159
  children: AnyNode[];
146
160
  }
147
161
  type ShadowValue = 'none' | 'sm' | 'md' | 'lg' | 'xl';
148
- interface CardNode extends BaseNode, CommonProps {
162
+ interface CardNode extends BaseNode, CommonProps, InteractiveProps {
149
163
  type: 'Card';
150
164
  title?: string | null;
151
165
  shadow?: ShadowValue;
@@ -155,12 +169,16 @@ interface CardNode extends BaseNode, CommonProps {
155
169
  interface ModalNode extends BaseNode, CommonProps {
156
170
  type: 'Modal';
157
171
  title?: string | null;
172
+ /** Unique identifier for targeting with opens/toggles */
173
+ id?: string;
158
174
  children: AnyNode[];
159
175
  }
160
176
  type DrawerPosition = 'left' | 'right' | 'top' | 'bottom';
161
177
  interface DrawerNode extends BaseNode, CommonProps {
162
178
  type: 'Drawer';
163
179
  title?: string | null;
180
+ /** Unique identifier for targeting with opens/toggles */
181
+ id?: string;
164
182
  position?: DrawerPosition;
165
183
  children: AnyNode[];
166
184
  }
@@ -189,7 +207,7 @@ interface TitleNode extends BaseNode, Omit<CommonProps, 'align'> {
189
207
  size?: TextSize;
190
208
  align?: TextAlign;
191
209
  }
192
- interface LinkNode extends BaseNode, CommonProps {
210
+ interface LinkNode extends BaseNode, CommonProps, InteractiveProps {
193
211
  type: 'Link';
194
212
  content: string;
195
213
  href?: string;
@@ -259,7 +277,7 @@ interface SliderNode extends BaseNode, CommonProps {
259
277
  }
260
278
  type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
261
279
  type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
262
- interface ButtonNode extends BaseNode, CommonProps {
280
+ interface ButtonNode extends BaseNode, CommonProps, InteractiveProps {
263
281
  type: 'Button';
264
282
  content: string;
265
283
  primary?: boolean;
@@ -272,7 +290,7 @@ interface ButtonNode extends BaseNode, CommonProps {
272
290
  disabled?: boolean;
273
291
  loading?: boolean;
274
292
  }
275
- interface ImageNode extends BaseNode, CommonProps {
293
+ interface ImageNode extends BaseNode, CommonProps, InteractiveProps {
276
294
  type: 'Image';
277
295
  src?: string | null;
278
296
  alt?: string;
@@ -283,7 +301,7 @@ interface PlaceholderNode extends BaseNode, CommonProps {
283
301
  children?: AnyNode[];
284
302
  }
285
303
  type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
286
- interface AvatarNode extends BaseNode, CommonProps {
304
+ interface AvatarNode extends BaseNode, CommonProps, InteractiveProps {
287
305
  type: 'Avatar';
288
306
  name?: string | null;
289
307
  src?: boolean;
@@ -291,7 +309,7 @@ interface AvatarNode extends BaseNode, CommonProps {
291
309
  }
292
310
  type BadgeVariant = 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
293
311
  type BadgeSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
294
- interface BadgeNode extends BaseNode, CommonProps {
312
+ interface BadgeNode extends BaseNode, CommonProps, InteractiveProps {
295
313
  type: 'Badge';
296
314
  content: string;
297
315
  variant?: BadgeVariant;
@@ -300,7 +318,7 @@ interface BadgeNode extends BaseNode, CommonProps {
300
318
  size?: BadgeSize;
301
319
  }
302
320
  type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
303
- interface IconNode extends BaseNode, CommonProps {
321
+ interface IconNode extends BaseNode, CommonProps, InteractiveProps {
304
322
  type: 'Icon';
305
323
  name: string;
306
324
  size?: IconSize | number;
@@ -365,9 +383,10 @@ interface PopoverNode extends BaseNode, CommonProps {
365
383
  title?: string | null;
366
384
  children: AnyNode[];
367
385
  }
368
- interface DropdownItemNode {
386
+ interface DropdownItemNode extends InteractiveProps {
369
387
  label: string;
370
388
  icon?: string;
389
+ href?: string;
371
390
  danger?: boolean;
372
391
  disabled?: boolean;
373
392
  }
@@ -379,7 +398,7 @@ interface DropdownNode extends BaseNode, CommonProps {
379
398
  items: (DropdownItemNode | DividerNode)[];
380
399
  }
381
400
  /** Nav item for array syntax: nav ["a", "b"] */
382
- interface NavItem {
401
+ interface NavItem extends InteractiveProps {
383
402
  label: string;
384
403
  icon?: string;
385
404
  href?: string;
@@ -387,7 +406,7 @@ interface NavItem {
387
406
  disabled?: boolean;
388
407
  }
389
408
  /** Nav item for block syntax: item "label" icon="x" active */
390
- interface NavBlockItem {
409
+ interface NavBlockItem extends InteractiveProps {
391
410
  type: 'item';
392
411
  label: string;
393
412
  icon?: string;
@@ -428,7 +447,7 @@ interface TabsNode extends BaseNode, CommonProps {
428
447
  active?: number;
429
448
  children: TabNode[];
430
449
  }
431
- interface BreadcrumbItem {
450
+ interface BreadcrumbItem extends InteractiveProps {
432
451
  label: string;
433
452
  href?: string;
434
453
  }
@@ -454,4 +473,4 @@ type LeafNode = TextContentNode | InputComponentNode | ButtonNode | DisplayNode
454
473
  type AnyNode = ContainerNode | LeafNode;
455
474
  type NodeType = 'Document' | 'Page' | 'Header' | 'Main' | 'Footer' | 'Sidebar' | 'Section' | 'Row' | 'Col' | 'Card' | 'Modal' | 'Drawer' | 'Accordion' | 'Text' | 'Title' | 'Link' | 'Input' | 'Textarea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'Button' | 'Image' | 'Placeholder' | 'Avatar' | 'Badge' | 'Icon' | 'Table' | 'List' | 'Alert' | 'Toast' | 'Progress' | 'Spinner' | 'Tooltip' | 'Popover' | 'Dropdown' | 'Nav' | 'Tabs' | 'Breadcrumb' | 'Divider';
456
475
 
457
- export type { DividerComponentNode as $, AnyNode as A, ButtonNode as B, ContainerNode as C, DrawerNode as D, FeedbackNode as E, FooterNode as F, GridNode as G, HeaderNode as H, InputComponentNode as I, AlertNode as J, ToastNode as K, LeafNode as L, MainNode as M, ProgressNode as N, SpinnerNode as O, PageNode as P, OverlayNode as Q, RowNode as R, SidebarNode as S, TextContentNode as T, TooltipNode as U, PopoverNode as V, DropdownNode as W, NavigationNode as X, NavNode as Y, TabsNode as Z, BreadcrumbNode as _, LayoutNode as a, NodeType as a0, WireframeDocument as a1, Position as a2, SourceLocation as a3, BaseNode as a4, ValueWithUnit as a5, SpacingValue as a6, SpacingProps as a7, WidthValue as a8, HeightValue as a9, SpinnerSize as aA, TooltipPosition as aB, DropdownItemNode as aC, DividerNode as aD, NavItem as aE, NavBlockItem as aF, NavGroupNode as aG, NavDivider as aH, NavChild as aI, TabNode as aJ, BreadcrumbItem as aK, SizeProps as aa, JustifyValue as ab, AlignValue as ac, DirectionValue as ad, FlexProps as ae, GridProps as af, PositionProps as ag, CommonProps as ah, ShadowValue as ai, DrawerPosition as aj, TextSizeToken as ak, TextSize as al, TextWeight as am, TextAlign as an, TitleLevel as ao, InputType as ap, SelectOption as aq, ButtonVariant as ar, ButtonSize as as, AvatarSize as at, BadgeVariant as au, BadgeSize as av, IconSize as aw, ListItemNode as ax, AlertVariant as ay, ToastPosition as az, SectionNode as b, ColNode as c, ContainerComponentNode as d, CardNode as e, ModalNode as f, AccordionNode as g, TextNode as h, TitleNode as i, LinkNode as j, InputNode as k, TextareaNode as l, SelectNode as m, CheckboxNode as n, RadioNode as o, SwitchNode as p, SliderNode as q, DisplayNode as r, ImageNode as s, PlaceholderNode as t, AvatarNode as u, BadgeNode as v, IconNode as w, DataNode as x, TableNode as y, ListNode as z };
476
+ export type { DividerComponentNode as $, AnyNode as A, ButtonNode as B, ContainerNode as C, DrawerNode as D, FeedbackNode as E, FooterNode as F, GridNode as G, HeaderNode as H, InputComponentNode as I, AlertNode as J, ToastNode as K, LeafNode as L, MainNode as M, ProgressNode as N, SpinnerNode as O, PageNode as P, OverlayNode as Q, RowNode as R, SidebarNode as S, TextContentNode as T, TooltipNode as U, PopoverNode as V, DropdownNode as W, NavigationNode as X, NavNode as Y, TabsNode as Z, BreadcrumbNode as _, LayoutNode as a, NodeType as a0, WireframeDocument as a1, Position as a2, SourceLocation as a3, BaseNode as a4, ValueWithUnit as a5, SpacingValue as a6, SpacingProps as a7, WidthValue as a8, HeightValue as a9, ToastPosition as aA, SpinnerSize as aB, TooltipPosition as aC, DropdownItemNode as aD, DividerNode as aE, NavItem as aF, NavBlockItem as aG, NavGroupNode as aH, NavDivider as aI, NavChild as aJ, TabNode as aK, BreadcrumbItem as aL, SizeProps as aa, JustifyValue as ab, AlignValue as ac, DirectionValue as ad, FlexProps as ae, GridProps as af, PositionProps as ag, CommonProps as ah, InteractiveProps as ai, ShadowValue as aj, DrawerPosition as ak, TextSizeToken as al, TextSize as am, TextWeight as an, TextAlign as ao, TitleLevel as ap, InputType as aq, SelectOption as ar, ButtonVariant as as, ButtonSize as at, AvatarSize as au, BadgeVariant as av, BadgeSize as aw, IconSize as ax, ListItemNode as ay, AlertVariant as az, SectionNode as b, ColNode as c, ContainerComponentNode as d, CardNode as e, ModalNode as f, AccordionNode as g, TextNode as h, TitleNode as i, LinkNode as j, InputNode as k, TextareaNode as l, SelectNode as m, CheckboxNode as n, RadioNode as o, SwitchNode as p, SliderNode as q, DisplayNode as r, ImageNode as s, PlaceholderNode as t, AvatarNode as u, BadgeNode as v, IconNode as w, DataNode as x, TableNode as y, ListNode as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wireweave/core",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Core parser and renderer for wireweave",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",