@biela.dev/core 1.7.11 → 1.7.13

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
@@ -478,11 +478,25 @@ function registerCustomDeviceSVG(deviceId, svgString, frame, cropViewBox, screen
478
478
  let bodySVG = defsMatch ? processedSVG.replace(defsContent, defsPlaceholder) : processedSVG;
479
479
  bodySVG = bodySVG.replace(/<rect\b([^>]*?)\/?>/gi, (fullMatch, attrs) => {
480
480
  if (/\bmask\s*=/i.test(fullMatch)) return fullMatch;
481
- const xVal = parseFloat(attrs.match(/\bx\s*=\s*["']?(-?\d+\.?\d*)["']?/i)?.[1] ?? "0");
482
- const yVal = parseFloat(attrs.match(/\by\s*=\s*["']?(-?\d+\.?\d*)["']?/i)?.[1] ?? "0");
481
+ let xVal = parseFloat(attrs.match(/\bx\s*=\s*["']?(-?\d+\.?\d*)["']?/i)?.[1] ?? "0");
482
+ let yVal = parseFloat(attrs.match(/\by\s*=\s*["']?(-?\d+\.?\d*)["']?/i)?.[1] ?? "0");
483
483
  const wVal = parseFloat(attrs.match(/\bwidth\s*=\s*["']?(\d+\.?\d*)["']?/i)?.[1] ?? "0");
484
484
  const hVal = parseFloat(attrs.match(/\bheight\s*=\s*["']?(\d+\.?\d*)["']?/i)?.[1] ?? "0");
485
- if (wVal > 0 && hVal > 0 && xVal <= sx + 2 && yVal <= sy + 2 && xVal + wVal >= sx + sw - 2 && yVal + hVal >= sy + sh - 2) {
485
+ if (wVal <= 0 || hVal <= 0) return fullMatch;
486
+ const translateMatch = attrs.match(/transform\s*=\s*["'][^"']*translate\(\s*(-?[\d.]+)[\s,]+(-?[\d.]+)/i);
487
+ if (translateMatch) {
488
+ xVal += parseFloat(translateMatch[1]);
489
+ yVal += parseFloat(translateMatch[2]);
490
+ }
491
+ const fullyCovering = xVal <= sx + 2 && yVal <= sy + 2 && xVal + wVal >= sx + sw - 2 && yVal + hVal >= sy + sh - 2;
492
+ const overlapLeft = Math.max(xVal, sx);
493
+ const overlapTop = Math.max(yVal, sy);
494
+ const overlapRight = Math.min(xVal + wVal, sx + sw);
495
+ const overlapBottom = Math.min(yVal + hVal, sy + sh);
496
+ const overlapArea = Math.max(0, overlapRight - overlapLeft) * Math.max(0, overlapBottom - overlapTop);
497
+ const screenArea = sw * sh;
498
+ const significantOverlap = overlapArea > screenArea * 0.15 && wVal * hVal > screenArea * 0.25;
499
+ if (fullyCovering || significantOverlap) {
486
500
  return fullMatch.replace(/(\/?>)$/, ` mask="url(#${maskId})"$1`);
487
501
  }
488
502
  return fullMatch;
@@ -508,7 +522,11 @@ function registerCustomDeviceSVG(deviceId, svgString, frame, cropViewBox, screen
508
522
  bezelRight: Math.round((vbW - screenRect.x - screenRect.width) * s),
509
523
  bezelBottom: Math.round((vbH - screenRect.y - screenRect.height) * s),
510
524
  totalWidth: Math.round(vbW * s),
511
- totalHeight: Math.round(vbH * s)
525
+ totalHeight: Math.round(vbH * s),
526
+ // Derive screen corner radius from the SVG's screen rect rx,
527
+ // scaled to CSS pixels, so the content clipPath matches the
528
+ // SVG mask hole exactly (no corner gap mismatch).
529
+ screenRadius: screenRect.rx ? Math.round(screenRect.rx * s) : frame.screenRadius
512
530
  };
513
531
  }
514
532
  }
@@ -708,7 +726,7 @@ function DeviceFrame({
708
726
  top: frameBezelTop,
709
727
  width: deviceMeta.screen.width,
710
728
  height: deviceMeta.screen.height,
711
- clipPath: `inset(0 round ${contract.screen.cornerRadius}px)`,
729
+ clipPath: `inset(0 round ${frameInfo?.screenRadius ?? contract.screen.cornerRadius}px)`,
712
730
  overflow: "hidden",
713
731
  backfaceVisibility: "hidden",
714
732
  transform: "translateZ(0)",
@@ -861,11 +879,20 @@ var CustomSVGStore = class {
861
879
  }
862
880
  }
863
881
  persist(all) {
864
- if (!this.storage) return;
865
882
  const json = JSON.stringify(all);
866
- try {
867
- this.storage.setItem(SVG_OVERRIDES_KEY, json);
868
- } catch {
883
+ if (this.storage) {
884
+ try {
885
+ this.storage.setItem(SVG_OVERRIDES_KEY, json);
886
+ } catch {
887
+ }
888
+ }
889
+ if (typeof fetch !== "undefined") {
890
+ fetch("/api/storage/svg-overrides", {
891
+ method: "PUT",
892
+ headers: { "Content-Type": "application/json" },
893
+ body: json
894
+ }).catch(() => {
895
+ });
869
896
  }
870
897
  }
871
898
  };