@biela.dev/core 1.7.12 → 1.7.14

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,10 +726,11 @@ 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)",
733
+ zIndex: 12,
715
734
  ...cssVarStyle
716
735
  },
717
736
  children: /* @__PURE__ */ jsxRuntime.jsx(DeviceErrorBoundary, { children })
@@ -896,6 +915,8 @@ registerDeviceSVG("iphone-se-3", devices.IPhoneSE3SVG, devices.IPHONE_SE_3_FRAME
896
915
  registerDeviceSVG("galaxy-s25-ultra", devices.GalaxyS25UltraSVG, devices.GALAXY_S25_ULTRA_FRAME);
897
916
  registerDeviceSVG("galaxy-s25", devices.GalaxyS25SVG, devices.GALAXY_S25_FRAME);
898
917
  registerDeviceSVG("galaxy-s25-edge", devices.GalaxyS25EdgeSVG, devices.GALAXY_S25_EDGE_FRAME);
918
+ registerDeviceSVG("galaxy-z-fold-7", devices.GalaxyZFold7SVG, devices.GALAXY_Z_FOLD_7_FRAME);
919
+ registerDeviceSVG("galaxy-z-fold-7-open", devices.GalaxyZFold7OpenSVG, devices.GALAXY_Z_FOLD_7_OPEN_FRAME);
899
920
  registerDeviceSVG("pixel-9-pro-xl", devices.Pixel9ProXLSVG, devices.PIXEL_9_PRO_XL_FRAME);
900
921
  registerDeviceSVG("pixel-9-pro", devices.Pixel9ProSVG, devices.PIXEL_9_PRO_FRAME);
901
922
  getCustomSVGStore().applyAll();
@@ -993,6 +1014,21 @@ function useOrientation(initial = "portrait") {
993
1014
  setOrientation
994
1015
  };
995
1016
  }
1017
+ function useFoldState(baseDeviceId, initial = "folded") {
1018
+ const [foldState, setFoldState] = react.useState(initial);
1019
+ const toggle = react.useCallback(
1020
+ () => setFoldState((s) => s === "folded" ? "open" : "folded"),
1021
+ []
1022
+ );
1023
+ const deviceId = foldState === "open" ? `${baseDeviceId}-open` : baseDeviceId;
1024
+ return {
1025
+ foldState,
1026
+ isOpen: foldState === "open",
1027
+ deviceId,
1028
+ toggle,
1029
+ setFoldState
1030
+ };
1031
+ }
996
1032
  function DeviceCompare({
997
1033
  deviceA,
998
1034
  deviceB,
@@ -1491,6 +1527,7 @@ exports.snapToStep = snapToStep;
1491
1527
  exports.useAdaptiveScale = useAdaptiveScale;
1492
1528
  exports.useContainerSize = useContainerSize;
1493
1529
  exports.useDeviceContract = useDeviceContract;
1530
+ exports.useFoldState = useFoldState;
1494
1531
  exports.useOrientation = useOrientation;
1495
1532
  exports.useScreenPower = useScreenPower;
1496
1533
  exports.useVolumeControl = useVolumeControl;