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