canvu-react 0.3.38 → 0.3.39

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.
@@ -1,5 +1,5 @@
1
1
  import { V as VectorSceneItem } from './types-Bnq2HtHQ.js';
2
- import { x as VectorViewportAssetStore } from './shape-builders-CsSXKCcs.js';
2
+ import { E as VectorViewportAssetStore } from './shape-builders-C7bxJBGR.js';
3
3
 
4
4
  declare class IndexedDbImageStore {
5
5
  private dbPromise;
@@ -1,5 +1,5 @@
1
1
  import { V as VectorSceneItem } from './types-Bnq2HtHQ.cjs';
2
- import { x as VectorViewportAssetStore } from './shape-builders-CsbSRZnQ.cjs';
2
+ import { E as VectorViewportAssetStore } from './shape-builders-Dedcl6tw.cjs';
3
3
 
4
4
  declare class IndexedDbImageStore {
5
5
  private dbPromise;
@@ -1,9 +1,9 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { C as CanvasPlugin } from './types-DWGk2_GZ.cjs';
2
+ import { C as CanvasPlugin } from './types-DUW61Tjy.cjs';
3
3
  import 'react';
4
4
  import './types-Bnq2HtHQ.cjs';
5
5
  import './camera-Di5R_Rwl.cjs';
6
- import './shape-builders-CsbSRZnQ.cjs';
6
+ import './shape-builders-Dedcl6tw.cjs';
7
7
 
8
8
  type ChatbotPluginPanelProps = {
9
9
  /**
package/dist/chatbot.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { C as CanvasPlugin } from './types-B6PAYKzx.js';
2
+ import { C as CanvasPlugin } from './types-BBb8KoyW.js';
3
3
  import 'react';
4
4
  import './types-Bnq2HtHQ.js';
5
5
  import './camera-AoTwBSoE.js';
6
- import './shape-builders-CsSXKCcs.js';
6
+ import './shape-builders-C7bxJBGR.js';
7
7
 
8
8
  type ChatbotPluginPanelProps = {
9
9
  /**
package/dist/index.cjs CHANGED
@@ -2761,6 +2761,105 @@ function cloneVectorSceneItemsWithNewIds(items) {
2761
2761
  return items.map(cloneVectorSceneItemWithNewId);
2762
2762
  }
2763
2763
 
2764
+ // src/scene/link-item.ts
2765
+ var LINK_PLUGIN_KEY = "canvuLink";
2766
+ var DEFAULT_LINK_CARD_WIDTH = 360;
2767
+ var DEFAULT_LINK_CARD_HEIGHT = 132;
2768
+ var LINK_CARD_BORDER = "#e2e8f0";
2769
+ var LINK_CARD_ACCENT = "#2563eb";
2770
+ var LINK_CARD_TITLE_COLOR = "#0f172a";
2771
+ var LINK_CARD_TEXT_COLOR = "#475569";
2772
+ var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
2773
+ var formatNumber = (value) => {
2774
+ const rounded = Math.round(value * 100) / 100;
2775
+ return Object.is(rounded, -0) ? "0" : String(rounded);
2776
+ };
2777
+ var escapeXmlAttribute = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2778
+ var escapeHtmlText2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
2779
+ var getLinkHostname = (href) => {
2780
+ try {
2781
+ return new URL(href).hostname.replace(/^www\./, "");
2782
+ } catch {
2783
+ return href;
2784
+ }
2785
+ };
2786
+ var buildLinkTextBand = (band) => {
2787
+ const lineHeight = band.fontSize * 1.3;
2788
+ const weight = band.fontWeight != null ? `font-weight:${band.fontWeight};` : "";
2789
+ const lineClampStyle = band.clampLines ? `display:-webkit-box;-webkit-line-clamp:${band.clampLines};-webkit-box-orient:vertical;` : "";
2790
+ return `<foreignObject x="${formatNumber(band.x)}" y="${formatNumber(band.y)}" width="${formatNumber(Math.max(1, band.width))}" height="${formatNumber(Math.max(1, band.height))}"><div xmlns="http://www.w3.org/1999/xhtml" style="box-sizing:border-box;width:100%;height:100%;margin:0;font-family:system-ui,sans-serif;font-size:${formatNumber(band.fontSize)}px;line-height:${formatNumber(lineHeight)}px;color:${band.color};overflow:hidden;word-break:break-word;${lineClampStyle}${weight}">${escapeHtmlText2(band.text)}</div></foreignObject>`;
2791
+ };
2792
+ function buildLinkCardSvg(width, height, link) {
2793
+ const cardWidth = Math.max(1, width);
2794
+ const cardHeight = Math.max(1, height);
2795
+ const padding = 14;
2796
+ const badgeSize = clamp(Math.min(72, cardHeight - padding * 2), 28, 96);
2797
+ const textX = padding + badgeSize + 14;
2798
+ const textWidth = Math.max(1, cardWidth - textX - padding);
2799
+ const hostname = getLinkHostname(link.href);
2800
+ const title = link.title?.trim() || hostname || "Link";
2801
+ const description = link.description?.trim() || link.href;
2802
+ const titleY = padding;
2803
+ const titleHeight = clamp(cardHeight * 0.22, 18, 28);
2804
+ const hostY = titleY + titleHeight + 2;
2805
+ const hostHeight = 16;
2806
+ const descY = hostY + hostHeight + 4;
2807
+ const descHeight = Math.max(1, cardHeight - descY - padding);
2808
+ const badge = link.favicon ? `<clipPath id="canvu-link-badge"><rect x="${formatNumber(padding)}" y="${formatNumber(padding)}" width="${formatNumber(badgeSize)}" height="${formatNumber(badgeSize)}" rx="12" /></clipPath>
2809
+ <rect x="${formatNumber(padding)}" y="${formatNumber(padding)}" width="${formatNumber(badgeSize)}" height="${formatNumber(badgeSize)}" rx="12" fill="#f8fafc" stroke="${LINK_CARD_BORDER}" stroke-width="1" />
2810
+ <image href="${escapeXmlAttribute(link.favicon)}" x="${formatNumber(padding)}" y="${formatNumber(padding)}" width="${formatNumber(badgeSize)}" height="${formatNumber(badgeSize)}" preserveAspectRatio="xMidYMid slice" clip-path="url(#canvu-link-badge)" />` : `<rect x="${formatNumber(padding)}" y="${formatNumber(padding)}" width="${formatNumber(badgeSize)}" height="${formatNumber(badgeSize)}" rx="12" fill="${LINK_CARD_ACCENT}" fill-opacity="0.1" stroke="${LINK_CARD_ACCENT}" stroke-opacity="0.3" stroke-width="1" />
2811
+ <g transform="translate(${formatNumber(padding + badgeSize / 2)},${formatNumber(padding + badgeSize / 2)})" stroke="${LINK_CARD_ACCENT}" stroke-width="2.4" stroke-linecap="round" fill="none">
2812
+ <path d="M-9 3 a6 6 0 0 1 0 -8 l4 -4 a6 6 0 0 1 8 8 l-2 2" />
2813
+ <path d="M9 -3 a6 6 0 0 1 0 8 l-4 4 a6 6 0 0 1 -8 -8 l2 -2" />
2814
+ </g>`;
2815
+ const externalIconX = cardWidth - padding - 16;
2816
+ const externalIcon = `<g transform="translate(${formatNumber(externalIconX)},${formatNumber(padding)})" stroke="${LINK_CARD_TEXT_COLOR}" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none">
2817
+ <path d="M6 1 H11 V6" />
2818
+ <path d="M11 1 L4.5 7.5" />
2819
+ <path d="M9 7 V10 a1 1 0 0 1 -1 1 H2 a1 1 0 0 1 -1 -1 V4 a1 1 0 0 1 1 -1 H5" />
2820
+ </g>`;
2821
+ return `
2822
+ <rect width="${formatNumber(cardWidth)}" height="${formatNumber(cardHeight)}" rx="16" fill="#ffffff" stroke="${LINK_CARD_BORDER}" stroke-width="1.5" />
2823
+ ${badge}
2824
+ ${externalIcon}
2825
+ ${buildLinkTextBand({ x: textX, y: titleY, width: textWidth - 18, height: titleHeight, text: title, fontSize: 15, color: LINK_CARD_TITLE_COLOR, fontWeight: 700, clampLines: 1 })}
2826
+ ${buildLinkTextBand({ x: textX, y: hostY, width: textWidth, height: hostHeight, text: hostname, fontSize: 12, color: LINK_CARD_ACCENT, clampLines: 1 })}
2827
+ ${buildLinkTextBand({ x: textX, y: descY, width: textWidth, height: descHeight, text: description, fontSize: 12, color: LINK_CARD_TEXT_COLOR, clampLines: 2 })}
2828
+ `;
2829
+ }
2830
+ var isCanvuLinkData = (value) => {
2831
+ if (!value || typeof value !== "object") return false;
2832
+ const candidate = value;
2833
+ return typeof candidate.href === "string" && candidate.href.length > 0;
2834
+ };
2835
+ function getLinkData(item) {
2836
+ const entry = item.pluginData?.[LINK_PLUGIN_KEY];
2837
+ return isCanvuLinkData(entry) ? entry : null;
2838
+ }
2839
+ function isLinkItem(item) {
2840
+ return getLinkData(item) != null;
2841
+ }
2842
+ function createLinkItem(id, bounds, link) {
2843
+ const width = bounds.width || DEFAULT_LINK_CARD_WIDTH;
2844
+ const height = bounds.height || DEFAULT_LINK_CARD_HEIGHT;
2845
+ const item = createCustomShapeItem(
2846
+ id,
2847
+ { ...bounds, width, height },
2848
+ { render: (size) => buildLinkCardSvg(size.width, size.height, link) }
2849
+ );
2850
+ return {
2851
+ ...item,
2852
+ pluginData: {
2853
+ ...item.pluginData ?? {},
2854
+ [LINK_PLUGIN_KEY]: link
2855
+ }
2856
+ };
2857
+ }
2858
+ var DEFAULT_LINK_CARD_SIZE = {
2859
+ width: DEFAULT_LINK_CARD_WIDTH,
2860
+ height: DEFAULT_LINK_CARD_HEIGHT
2861
+ };
2862
+
2764
2863
  // src/scene/managed-images.ts
2765
2864
  var MANAGED_KEY = "managed";
2766
2865
  var STACK_GAP_WORLD = 16;
@@ -2865,8 +2964,10 @@ var VectorScene = class {
2865
2964
 
2866
2965
  exports.ARROW_BIND_SNAP_PX = ARROW_BIND_SNAP_PX;
2867
2966
  exports.Camera2D = Camera2D;
2967
+ exports.DEFAULT_LINK_CARD_SIZE = DEFAULT_LINK_CARD_SIZE;
2868
2968
  exports.DEFAULT_STROKE_STYLE = DEFAULT_STROKE_STYLE;
2869
2969
  exports.DEFAULT_TEXT_FONT_SIZE = DEFAULT_TEXT_FONT_SIZE;
2970
+ exports.LINK_PLUGIN_KEY = LINK_PLUGIN_KEY;
2870
2971
  exports.MANAGED_KEY = MANAGED_KEY;
2871
2972
  exports.MAX_RASTER_EMBED_DIMENSION = MAX_RASTER_EMBED_DIMENSION;
2872
2973
  exports.SvgVectorRenderer = SvgVectorRenderer;
@@ -2884,6 +2985,7 @@ exports.buildDrawDotSvg = buildDrawDotSvg;
2884
2985
  exports.buildEllipseSvg = buildEllipseSvg;
2885
2986
  exports.buildFreehandPathSvg = buildFreehandPathSvg;
2886
2987
  exports.buildLineSvg = buildLineSvg;
2988
+ exports.buildLinkCardSvg = buildLinkCardSvg;
2887
2989
  exports.buildRectSvg = buildRectSvg;
2888
2990
  exports.buildTextSvg = buildTextSvg;
2889
2991
  exports.cloneVectorSceneItemWithNewId = cloneVectorSceneItemWithNewId;
@@ -2899,6 +3001,7 @@ exports.createFreehandStrokeItem = createFreehandStrokeItem;
2899
3001
  exports.createImageFromVectorTrace = createImageFromVectorTrace;
2900
3002
  exports.createImageItem = createImageItem;
2901
3003
  exports.createLineItem = createLineItem;
3004
+ exports.createLinkItem = createLinkItem;
2902
3005
  exports.createRectangleItem = createRectangleItem;
2903
3006
  exports.createShapeId = createShapeId;
2904
3007
  exports.createTextItem = createTextItem;
@@ -2908,9 +3011,11 @@ exports.encodeCanvasToBlob = encodeCanvasToBlob;
2908
3011
  exports.expandCustomShapeTemplate = expandCustomShapeTemplate;
2909
3012
  exports.formatCameraTransform = formatCameraTransform;
2910
3013
  exports.formatItemPlacementTransform = formatItemPlacementTransform;
3014
+ exports.getLinkData = getLinkData;
2911
3015
  exports.hitTestWorldPoint = hitTestWorldPoint;
2912
3016
  exports.hydrateSceneItemsWithAssets = hydrateSceneItemsWithAssets;
2913
3017
  exports.isArrowBindTarget = isArrowBindTarget;
3018
+ exports.isLinkItem = isLinkItem;
2914
3019
  exports.isManagedImage = isManagedImage;
2915
3020
  exports.itemHitTestWorldPoint = itemHitTestWorldPoint;
2916
3021
  exports.lineEndpointsToLocal = lineEndpointsToLocal;