@sprawlify/primitives 0.0.55 → 0.0.56

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.
Files changed (84) hide show
  1. package/dist/collection.d.cts +2 -2
  2. package/dist/collection.d.mts +2 -2
  3. package/dist/date-utils.d.cts +5 -5
  4. package/dist/date-utils.d.mts +1 -1
  5. package/dist/{index-HnPpYuSl.d.mts → index-BqhWpjZh.d.mts} +5 -5
  6. package/dist/{list-collection-CTt1eong.d.mts → list-collection-BbgocToA.d.mts} +1 -1
  7. package/dist/{list-collection-BvMwDNHf.d.cts → list-collection-DettiQL3.d.cts} +1 -1
  8. package/dist/machines/angle-slider/index.d.cts +1 -1
  9. package/dist/machines/angle-slider/index.d.mts +1 -1
  10. package/dist/machines/bottom-sheet/index.d.cts +1 -1
  11. package/dist/machines/bottom-sheet/index.d.mts +1 -1
  12. package/dist/machines/carousel/index.d.cts +1 -1
  13. package/dist/machines/carousel/index.d.mts +1 -1
  14. package/dist/machines/clipboard/index.d.cts +1 -1
  15. package/dist/machines/clipboard/index.d.mts +1 -1
  16. package/dist/machines/collapsible/index.d.cts +1 -1
  17. package/dist/machines/collapsible/index.d.mts +1 -1
  18. package/dist/machines/color-picker/index.d.cts +1 -1
  19. package/dist/machines/color-picker/index.d.mts +1 -1
  20. package/dist/machines/combobox/index.d.cts +2 -2
  21. package/dist/machines/combobox/index.d.mts +2 -2
  22. package/dist/machines/date-picker/index.d.cts +1 -1
  23. package/dist/machines/date-picker/index.d.mts +2 -2
  24. package/dist/machines/dialog/index.d.cts +1 -1
  25. package/dist/machines/dialog/index.d.mts +1 -1
  26. package/dist/machines/editable/index.d.cts +1 -1
  27. package/dist/machines/editable/index.d.mts +1 -1
  28. package/dist/machines/file-upload/index.d.cts +1 -1
  29. package/dist/machines/file-upload/index.d.mts +1 -1
  30. package/dist/machines/floating-panel/index.d.cts +1 -1
  31. package/dist/machines/floating-panel/index.d.mts +1 -1
  32. package/dist/machines/hover-card/index.d.cts +1 -1
  33. package/dist/machines/hover-card/index.d.mts +1 -1
  34. package/dist/machines/image-cropper/index.cjs +90 -29
  35. package/dist/machines/image-cropper/index.d.cts +1 -1
  36. package/dist/machines/image-cropper/index.d.mts +1 -1
  37. package/dist/machines/image-cropper/index.mjs +90 -29
  38. package/dist/machines/listbox/index.d.cts +3 -3
  39. package/dist/machines/listbox/index.d.mts +3 -3
  40. package/dist/machines/marquee/index.d.cts +3 -3
  41. package/dist/machines/marquee/index.d.mts +3 -3
  42. package/dist/machines/menu/index.d.cts +1 -1
  43. package/dist/machines/menu/index.d.mts +1 -1
  44. package/dist/machines/navigation-menu/index.d.cts +1 -1
  45. package/dist/machines/navigation-menu/index.d.mts +1 -1
  46. package/dist/machines/number-input/index.d.cts +1 -1
  47. package/dist/machines/number-input/index.d.mts +1 -1
  48. package/dist/machines/pagination/index.d.cts +1 -1
  49. package/dist/machines/pagination/index.d.mts +1 -1
  50. package/dist/machines/popover/index.d.cts +1 -1
  51. package/dist/machines/popover/index.d.mts +1 -1
  52. package/dist/machines/progress/index.d.cts +1 -1
  53. package/dist/machines/progress/index.d.mts +1 -1
  54. package/dist/machines/radio-group/index.d.cts +1 -1
  55. package/dist/machines/radio-group/index.d.mts +1 -1
  56. package/dist/machines/rating-group/index.d.cts +1 -1
  57. package/dist/machines/rating-group/index.d.mts +1 -1
  58. package/dist/machines/scroll-area/index.d.cts +1 -1
  59. package/dist/machines/scroll-area/index.d.mts +1 -1
  60. package/dist/machines/select/index.d.cts +2 -2
  61. package/dist/machines/select/index.d.mts +2 -2
  62. package/dist/machines/slider/index.d.cts +1 -1
  63. package/dist/machines/slider/index.d.mts +1 -1
  64. package/dist/machines/steps/index.d.cts +1 -1
  65. package/dist/machines/steps/index.d.mts +1 -1
  66. package/dist/machines/switch/index.d.cts +1 -1
  67. package/dist/machines/switch/index.d.mts +1 -1
  68. package/dist/machines/tabs/index.d.cts +1 -1
  69. package/dist/machines/tabs/index.d.mts +1 -1
  70. package/dist/machines/tags-input/index.d.cts +1 -1
  71. package/dist/machines/tags-input/index.d.mts +1 -1
  72. package/dist/machines/timer/index.d.cts +1 -1
  73. package/dist/machines/timer/index.d.mts +1 -1
  74. package/dist/machines/toast/index.d.cts +1 -1
  75. package/dist/machines/toast/index.d.mts +1 -1
  76. package/dist/machines/tooltip/index.d.cts +1 -1
  77. package/dist/machines/tooltip/index.d.mts +1 -1
  78. package/dist/machines/tour/index.d.cts +1 -1
  79. package/dist/machines/tour/index.d.mts +1 -1
  80. package/dist/machines/tree-view/index.d.cts +1 -1
  81. package/dist/machines/tree-view/index.d.mts +1 -1
  82. package/dist/{selection-JDFmyke7.d.mts → selection-CTaapzrB.d.mts} +1 -1
  83. package/dist/{selection-vng1guNc.d.cts → selection-D3b3yV_x.d.cts} +1 -1
  84. package/package.json +1 -1
@@ -130,13 +130,18 @@ function drawCroppedImageToCanvas(params) {
130
130
  //#endregion
131
131
  //#region src/machines/image-cropper/image-cropper.utils.ts
132
132
  const { min, max, abs, round, hypot, PI, cos, sin } = Math;
133
- const isLeftHandle = (handlePosition) => handlePosition === "w" || handlePosition === "nw" || handlePosition === "sw";
134
- const isRightHandle = (handlePosition) => handlePosition === "e" || handlePosition === "ne" || handlePosition === "se";
135
- const isTopHandle = (handlePosition) => handlePosition === "n" || handlePosition === "nw" || handlePosition === "ne";
136
- const isBottomHandle = (handlePosition) => handlePosition === "s" || handlePosition === "sw" || handlePosition === "se";
137
- const isCornerHandle = (handlePosition) => (isLeftHandle(handlePosition) || isRightHandle(handlePosition)) && (isTopHandle(handlePosition) || isBottomHandle(handlePosition));
138
- const isHorizontalEdgeHandle = (handlePosition) => (isLeftHandle(handlePosition) || isRightHandle(handlePosition)) && !(isTopHandle(handlePosition) || isBottomHandle(handlePosition));
139
- const isVerticalEdgeHandle = (handlePosition) => (isTopHandle(handlePosition) || isBottomHandle(handlePosition)) && !(isLeftHandle(handlePosition) || isRightHandle(handlePosition));
133
+ const ASPECT_RATIO_TOLERANCE = .001;
134
+ const MIN_PINCH_DISTANCE = 1;
135
+ const isAspectRatioEqual = (a, b) => {
136
+ return abs(a - b) < ASPECT_RATIO_TOLERANCE;
137
+ };
138
+ const isLeftHandle = (v) => v === "w" || v === "nw" || v === "sw";
139
+ const isRightHandle = (v) => v === "e" || v === "ne" || v === "se";
140
+ const isTopHandle = (v) => v === "n" || v === "nw" || v === "ne";
141
+ const isBottomHandle = (v) => v === "s" || v === "sw" || v === "se";
142
+ const isCornerHandle = (v) => (isLeftHandle(v) || isRightHandle(v)) && (isTopHandle(v) || isBottomHandle(v));
143
+ const isHorizontalEdgeHandle = (v) => (isLeftHandle(v) || isRightHandle(v)) && !(isTopHandle(v) || isBottomHandle(v));
144
+ const isVerticalEdgeHandle = (v) => (isTopHandle(v) || isBottomHandle(v)) && !(isLeftHandle(v) || isRightHandle(v));
140
145
  const hasAspectRatio = (value) => typeof value === "number" && value > 0;
141
146
  const resolveSizeLimits = (options) => {
142
147
  const { minSize, maxSize, viewportSize, aspectRatio } = options;
@@ -508,10 +513,10 @@ function computeMoveCrop(cropStart, delta, viewportRect) {
508
513
  };
509
514
  }
510
515
  function clampOffset(params) {
511
- const { zoom, rotation, viewportSize, offset, fixedCropArea, crop, naturalSize } = params;
516
+ const { zoom, rotation, viewportSize, offset, fixedCropArea, crop } = params;
512
517
  const { cos: cos$1, sin: sin$1 } = getRotationTransform(rotation);
513
- if (fixedCropArea && crop && naturalSize) {
514
- const aabb$1 = computeAABB(naturalSize, zoom, cos$1, sin$1);
518
+ if (fixedCropArea && crop) {
519
+ const aabb$1 = computeAABB(viewportSize, zoom, cos$1, sin$1);
515
520
  const center = getViewportCenter(viewportSize);
516
521
  const cropRight = crop.x + crop.width;
517
522
  const cropBottom = crop.y + crop.height;
@@ -780,6 +785,12 @@ const getMaxBounds = (cropSize, viewportSize) => ({
780
785
  x: max(0, viewportSize.width - cropSize.width),
781
786
  y: max(0, viewportSize.height - cropSize.height)
782
787
  });
788
+ const centerCropOnPoint = (cropSize, center, viewportSize) => {
789
+ return clampPoint({
790
+ x: center.x - cropSize.width / 2,
791
+ y: center.y - cropSize.height / 2
792
+ }, ZERO_POINT, getMaxBounds(cropSize, viewportSize));
793
+ };
783
794
  const isSameSize = (a, b) => {
784
795
  return a.width === b.width && a.height === b.height;
785
796
  };
@@ -1353,7 +1364,11 @@ const machine = require_core.createMachine({
1353
1364
  actions: ["resizeCrop"]
1354
1365
  },
1355
1366
  VIEWPORT_RESIZE: { actions: ["resizeViewport"] },
1356
- RESET: { actions: ["resetToInitialState"] }
1367
+ RESET: { actions: ["resetToInitialState"] },
1368
+ ADJUST_ASPECT_RATIO: {
1369
+ guard: "hasViewportRect",
1370
+ actions: ["adjustCropAspectRatio"]
1371
+ }
1357
1372
  },
1358
1373
  computed: {
1359
1374
  isMeasured: ({ context }) => isVisibleRect(context.get("viewportRect")) && isVisibleRect(context.get("crop")),
@@ -1370,6 +1385,12 @@ const machine = require_core.createMachine({
1370
1385
  src: "prop"
1371
1386
  });
1372
1387
  });
1388
+ track([() => prop("aspectRatio"), () => prop("cropShape")], () => {
1389
+ send({
1390
+ type: "ADJUST_ASPECT_RATIO",
1391
+ src: "prop"
1392
+ });
1393
+ });
1373
1394
  },
1374
1395
  states: {
1375
1396
  idle: {
@@ -1564,7 +1585,7 @@ const machine = require_core.createMachine({
1564
1585
  const { minSize, maxSize } = getCropSizeLimits(prop);
1565
1586
  if (!pointerStart || !cropStart) return;
1566
1587
  const currentPoint = event.point;
1567
- const delta = subtractPoints(currentPoint, pointerStart);
1588
+ let delta = subtractPoints(currentPoint, pointerStart);
1568
1589
  let nextCrop;
1569
1590
  if (handlePosition) {
1570
1591
  if (typeof aspectRatioProp === "undefined" && cropShape !== "circle") if (event.shiftKey) {
@@ -1579,6 +1600,10 @@ const machine = require_core.createMachine({
1579
1600
  if (lockRatio !== null && lockRatio > 0) aspectRatio = lockRatio;
1580
1601
  } else context.set("shiftLockRatio", null);
1581
1602
  else context.set("shiftLockRatio", null);
1603
+ if (event.altKey) delta = {
1604
+ x: delta.x * 2,
1605
+ y: delta.y * 2
1606
+ };
1582
1607
  nextCrop = computeResizeCrop({
1583
1608
  cropStart,
1584
1609
  handlePosition,
@@ -1588,6 +1613,15 @@ const machine = require_core.createMachine({
1588
1613
  maxSize,
1589
1614
  aspectRatio
1590
1615
  });
1616
+ if (event.altKey) {
1617
+ const originalCenter = getCenterPoint(cropStart);
1618
+ const pos = centerCropOnPoint(nextCrop, originalCenter, viewportRect);
1619
+ nextCrop = {
1620
+ ...nextCrop,
1621
+ x: pos.x,
1622
+ y: pos.y
1623
+ };
1624
+ }
1591
1625
  } else nextCrop = computeMoveCrop(cropStart, delta, viewportRect);
1592
1626
  context.set("crop", nextCrop);
1593
1627
  },
@@ -1602,8 +1636,7 @@ const machine = require_core.createMachine({
1602
1636
  viewportSize: context.get("viewportRect"),
1603
1637
  offset: addPoints(offsetStart, subtractPoints(point, pointerStart)),
1604
1638
  fixedCropArea: prop("fixedCropArea"),
1605
- crop: context.get("crop"),
1606
- naturalSize: context.get("naturalSize")
1639
+ crop: context.get("crop")
1607
1640
  });
1608
1641
  context.set("offset", nextOffset);
1609
1642
  },
@@ -1665,7 +1698,6 @@ const machine = require_core.createMachine({
1665
1698
  const currentOffset = context.get("offset");
1666
1699
  const rotation = context.get("rotation");
1667
1700
  const viewportRect = context.get("viewportRect");
1668
- const naturalSize = context.get("naturalSize");
1669
1701
  const fixedCropArea = prop("fixedCropArea");
1670
1702
  if (!point) point = getCenterPoint(crop);
1671
1703
  const step = Math.abs(prop("zoomStep"));
@@ -1687,8 +1719,7 @@ const machine = require_core.createMachine({
1687
1719
  viewportSize: viewportRect,
1688
1720
  offset,
1689
1721
  fixedCropArea,
1690
- crop,
1691
- naturalSize
1722
+ crop
1692
1723
  });
1693
1724
  };
1694
1725
  const nextZoom = calculateNextZoom();
@@ -1758,7 +1789,7 @@ const machine = require_core.createMachine({
1758
1789
  if (lastDistance != null && lastDistance > 0 && lastMidpoint != null) {
1759
1790
  const delta = lastDistance - distance;
1760
1791
  const scale = distance / lastDistance;
1761
- const hasSignificantZoom = Math.abs(delta) > 1;
1792
+ const hasSignificantZoom = Math.abs(delta) > MIN_PINCH_DISTANCE;
1762
1793
  const panDelta = subtractPoints(midpoint, lastMidpoint);
1763
1794
  send({
1764
1795
  type: "ZOOM",
@@ -1809,15 +1840,14 @@ const machine = require_core.createMachine({
1809
1840
  if (isSameSize(oldViewportRect, newViewportRect)) return;
1810
1841
  context.set("viewportRect", newViewportRect);
1811
1842
  const oldCrop = context.get("crop");
1812
- if (!isVisibleRect(oldViewportRect)) {
1813
- if (!isVisibleRect(oldCrop)) {
1814
- send({
1815
- type: "SET_DEFAULT_CROP",
1816
- src: "viewport-resize"
1817
- });
1818
- return;
1819
- }
1843
+ if (!isVisibleRect(oldCrop)) {
1844
+ send({
1845
+ type: "SET_DEFAULT_CROP",
1846
+ src: "viewport-resize"
1847
+ });
1848
+ return;
1820
1849
  }
1850
+ if (!isVisibleRect(oldViewportRect)) return;
1821
1851
  const aspectRatio = resolveCropAspectRatio(prop("cropShape"), prop("aspectRatio"));
1822
1852
  const { minSize, maxSize } = getCropSizeLimits(prop);
1823
1853
  const constrainedCrop = computeResizeCrop({
@@ -1840,12 +1870,42 @@ const machine = require_core.createMachine({
1840
1870
  height: constrainedCrop.height
1841
1871
  });
1842
1872
  },
1843
- resetToInitialState({ context }) {
1873
+ resetToInitialState({ context, send }) {
1844
1874
  context.set("zoom", context.initial("zoom"));
1845
1875
  context.set("rotation", context.initial("rotation"));
1846
1876
  context.set("flip", context.initial("flip"));
1847
1877
  context.set("offset", ZERO_POINT);
1848
- context.set("crop", context.initial("crop"));
1878
+ send({
1879
+ type: "SET_DEFAULT_CROP",
1880
+ src: "reset"
1881
+ });
1882
+ },
1883
+ adjustCropAspectRatio({ context, prop }) {
1884
+ const viewportRect = context.get("viewportRect");
1885
+ if (!isVisibleRect(viewportRect)) return;
1886
+ const crop = context.get("crop");
1887
+ if (!isVisibleRect(crop)) return;
1888
+ const aspectRatio = resolveCropAspectRatio(prop("cropShape"), prop("aspectRatio"));
1889
+ if (aspectRatio === void 0) return;
1890
+ if (isAspectRatioEqual(crop.width / crop.height, aspectRatio)) return;
1891
+ const { minSize, maxSize } = getCropSizeLimits(prop);
1892
+ const constrainedCrop = computeResizeCrop({
1893
+ cropStart: crop,
1894
+ handlePosition: "se",
1895
+ delta: ZERO_POINT,
1896
+ viewportRect,
1897
+ minSize,
1898
+ maxSize,
1899
+ aspectRatio
1900
+ });
1901
+ if (isSameSize(crop, constrainedCrop)) return;
1902
+ const pos = centerCropOnPoint(constrainedCrop, getCenterPoint(crop), viewportRect);
1903
+ context.set("crop", {
1904
+ x: pos.x,
1905
+ y: pos.y,
1906
+ width: constrainedCrop.width,
1907
+ height: constrainedCrop.height
1908
+ });
1849
1909
  }
1850
1910
  },
1851
1911
  effects: {
@@ -1855,7 +1915,8 @@ const machine = require_core.createMachine({
1855
1915
  type: "POINTER_MOVE",
1856
1916
  point: require_dom_query.getEventPoint(event),
1857
1917
  target: require_dom_query.getEventTarget(event),
1858
- shiftKey: event.shiftKey
1918
+ shiftKey: event.shiftKey,
1919
+ altKey: event.altKey
1859
1920
  });
1860
1921
  }
1861
1922
  function onPointerUp() {
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DejIu6
3
3
  import { _ as Size, b as NormalizeProps, g as RequiredBy, m as Rect, p as Point, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-Bqw3r34-.cjs";
4
4
 
5
5
  //#region src/machines/image-cropper/image-cropper.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "image" | "viewport" | "selection" | "handle" | "grid">;
6
+ declare const anatomy: AnatomyInstance<"root" | "viewport" | "image" | "selection" | "handle" | "grid">;
7
7
  //#endregion
8
8
  //#region src/machines/image-cropper/image-cropper.types.d.ts
9
9
  type HandlePosition = "n" | "e" | "s" | "w" | "ne" | "se" | "sw" | "nw";
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DL5AIQ
3
3
  import { _ as Size, b as NormalizeProps, g as RequiredBy, m as Rect, p as Point, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-BuUzJjaP.mjs";
4
4
 
5
5
  //#region src/machines/image-cropper/image-cropper.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "image" | "viewport" | "selection" | "handle" | "grid">;
6
+ declare const anatomy: AnatomyInstance<"root" | "viewport" | "image" | "selection" | "handle" | "grid">;
7
7
  //#endregion
8
8
  //#region src/machines/image-cropper/image-cropper.types.d.ts
9
9
  type HandlePosition = "n" | "e" | "s" | "w" | "ne" | "se" | "sw" | "nw";
@@ -130,13 +130,18 @@ function drawCroppedImageToCanvas(params) {
130
130
  //#endregion
131
131
  //#region src/machines/image-cropper/image-cropper.utils.ts
132
132
  const { min, max, abs, round, hypot, PI, cos, sin } = Math;
133
- const isLeftHandle = (handlePosition) => handlePosition === "w" || handlePosition === "nw" || handlePosition === "sw";
134
- const isRightHandle = (handlePosition) => handlePosition === "e" || handlePosition === "ne" || handlePosition === "se";
135
- const isTopHandle = (handlePosition) => handlePosition === "n" || handlePosition === "nw" || handlePosition === "ne";
136
- const isBottomHandle = (handlePosition) => handlePosition === "s" || handlePosition === "sw" || handlePosition === "se";
137
- const isCornerHandle = (handlePosition) => (isLeftHandle(handlePosition) || isRightHandle(handlePosition)) && (isTopHandle(handlePosition) || isBottomHandle(handlePosition));
138
- const isHorizontalEdgeHandle = (handlePosition) => (isLeftHandle(handlePosition) || isRightHandle(handlePosition)) && !(isTopHandle(handlePosition) || isBottomHandle(handlePosition));
139
- const isVerticalEdgeHandle = (handlePosition) => (isTopHandle(handlePosition) || isBottomHandle(handlePosition)) && !(isLeftHandle(handlePosition) || isRightHandle(handlePosition));
133
+ const ASPECT_RATIO_TOLERANCE = .001;
134
+ const MIN_PINCH_DISTANCE = 1;
135
+ const isAspectRatioEqual = (a, b) => {
136
+ return abs(a - b) < ASPECT_RATIO_TOLERANCE;
137
+ };
138
+ const isLeftHandle = (v) => v === "w" || v === "nw" || v === "sw";
139
+ const isRightHandle = (v) => v === "e" || v === "ne" || v === "se";
140
+ const isTopHandle = (v) => v === "n" || v === "nw" || v === "ne";
141
+ const isBottomHandle = (v) => v === "s" || v === "sw" || v === "se";
142
+ const isCornerHandle = (v) => (isLeftHandle(v) || isRightHandle(v)) && (isTopHandle(v) || isBottomHandle(v));
143
+ const isHorizontalEdgeHandle = (v) => (isLeftHandle(v) || isRightHandle(v)) && !(isTopHandle(v) || isBottomHandle(v));
144
+ const isVerticalEdgeHandle = (v) => (isTopHandle(v) || isBottomHandle(v)) && !(isLeftHandle(v) || isRightHandle(v));
140
145
  const hasAspectRatio = (value) => typeof value === "number" && value > 0;
141
146
  const resolveSizeLimits = (options) => {
142
147
  const { minSize, maxSize, viewportSize, aspectRatio } = options;
@@ -508,10 +513,10 @@ function computeMoveCrop(cropStart, delta, viewportRect) {
508
513
  };
509
514
  }
510
515
  function clampOffset(params) {
511
- const { zoom, rotation, viewportSize, offset, fixedCropArea, crop, naturalSize } = params;
516
+ const { zoom, rotation, viewportSize, offset, fixedCropArea, crop } = params;
512
517
  const { cos: cos$1, sin: sin$1 } = getRotationTransform(rotation);
513
- if (fixedCropArea && crop && naturalSize) {
514
- const aabb$1 = computeAABB(naturalSize, zoom, cos$1, sin$1);
518
+ if (fixedCropArea && crop) {
519
+ const aabb$1 = computeAABB(viewportSize, zoom, cos$1, sin$1);
515
520
  const center = getViewportCenter(viewportSize);
516
521
  const cropRight = crop.x + crop.width;
517
522
  const cropBottom = crop.y + crop.height;
@@ -780,6 +785,12 @@ const getMaxBounds = (cropSize, viewportSize) => ({
780
785
  x: max(0, viewportSize.width - cropSize.width),
781
786
  y: max(0, viewportSize.height - cropSize.height)
782
787
  });
788
+ const centerCropOnPoint = (cropSize, center, viewportSize) => {
789
+ return clampPoint({
790
+ x: center.x - cropSize.width / 2,
791
+ y: center.y - cropSize.height / 2
792
+ }, ZERO_POINT, getMaxBounds(cropSize, viewportSize));
793
+ };
783
794
  const isSameSize = (a, b) => {
784
795
  return a.width === b.width && a.height === b.height;
785
796
  };
@@ -1353,7 +1364,11 @@ const machine = createMachine({
1353
1364
  actions: ["resizeCrop"]
1354
1365
  },
1355
1366
  VIEWPORT_RESIZE: { actions: ["resizeViewport"] },
1356
- RESET: { actions: ["resetToInitialState"] }
1367
+ RESET: { actions: ["resetToInitialState"] },
1368
+ ADJUST_ASPECT_RATIO: {
1369
+ guard: "hasViewportRect",
1370
+ actions: ["adjustCropAspectRatio"]
1371
+ }
1357
1372
  },
1358
1373
  computed: {
1359
1374
  isMeasured: ({ context }) => isVisibleRect(context.get("viewportRect")) && isVisibleRect(context.get("crop")),
@@ -1370,6 +1385,12 @@ const machine = createMachine({
1370
1385
  src: "prop"
1371
1386
  });
1372
1387
  });
1388
+ track([() => prop("aspectRatio"), () => prop("cropShape")], () => {
1389
+ send({
1390
+ type: "ADJUST_ASPECT_RATIO",
1391
+ src: "prop"
1392
+ });
1393
+ });
1373
1394
  },
1374
1395
  states: {
1375
1396
  idle: {
@@ -1564,7 +1585,7 @@ const machine = createMachine({
1564
1585
  const { minSize, maxSize } = getCropSizeLimits(prop);
1565
1586
  if (!pointerStart || !cropStart) return;
1566
1587
  const currentPoint = event.point;
1567
- const delta = subtractPoints(currentPoint, pointerStart);
1588
+ let delta = subtractPoints(currentPoint, pointerStart);
1568
1589
  let nextCrop;
1569
1590
  if (handlePosition) {
1570
1591
  if (typeof aspectRatioProp === "undefined" && cropShape !== "circle") if (event.shiftKey) {
@@ -1579,6 +1600,10 @@ const machine = createMachine({
1579
1600
  if (lockRatio !== null && lockRatio > 0) aspectRatio = lockRatio;
1580
1601
  } else context.set("shiftLockRatio", null);
1581
1602
  else context.set("shiftLockRatio", null);
1603
+ if (event.altKey) delta = {
1604
+ x: delta.x * 2,
1605
+ y: delta.y * 2
1606
+ };
1582
1607
  nextCrop = computeResizeCrop({
1583
1608
  cropStart,
1584
1609
  handlePosition,
@@ -1588,6 +1613,15 @@ const machine = createMachine({
1588
1613
  maxSize,
1589
1614
  aspectRatio
1590
1615
  });
1616
+ if (event.altKey) {
1617
+ const originalCenter = getCenterPoint(cropStart);
1618
+ const pos = centerCropOnPoint(nextCrop, originalCenter, viewportRect);
1619
+ nextCrop = {
1620
+ ...nextCrop,
1621
+ x: pos.x,
1622
+ y: pos.y
1623
+ };
1624
+ }
1591
1625
  } else nextCrop = computeMoveCrop(cropStart, delta, viewportRect);
1592
1626
  context.set("crop", nextCrop);
1593
1627
  },
@@ -1602,8 +1636,7 @@ const machine = createMachine({
1602
1636
  viewportSize: context.get("viewportRect"),
1603
1637
  offset: addPoints(offsetStart, subtractPoints(point, pointerStart)),
1604
1638
  fixedCropArea: prop("fixedCropArea"),
1605
- crop: context.get("crop"),
1606
- naturalSize: context.get("naturalSize")
1639
+ crop: context.get("crop")
1607
1640
  });
1608
1641
  context.set("offset", nextOffset);
1609
1642
  },
@@ -1665,7 +1698,6 @@ const machine = createMachine({
1665
1698
  const currentOffset = context.get("offset");
1666
1699
  const rotation = context.get("rotation");
1667
1700
  const viewportRect = context.get("viewportRect");
1668
- const naturalSize = context.get("naturalSize");
1669
1701
  const fixedCropArea = prop("fixedCropArea");
1670
1702
  if (!point) point = getCenterPoint(crop);
1671
1703
  const step = Math.abs(prop("zoomStep"));
@@ -1687,8 +1719,7 @@ const machine = createMachine({
1687
1719
  viewportSize: viewportRect,
1688
1720
  offset,
1689
1721
  fixedCropArea,
1690
- crop,
1691
- naturalSize
1722
+ crop
1692
1723
  });
1693
1724
  };
1694
1725
  const nextZoom = calculateNextZoom();
@@ -1758,7 +1789,7 @@ const machine = createMachine({
1758
1789
  if (lastDistance != null && lastDistance > 0 && lastMidpoint != null) {
1759
1790
  const delta = lastDistance - distance;
1760
1791
  const scale = distance / lastDistance;
1761
- const hasSignificantZoom = Math.abs(delta) > 1;
1792
+ const hasSignificantZoom = Math.abs(delta) > MIN_PINCH_DISTANCE;
1762
1793
  const panDelta = subtractPoints(midpoint, lastMidpoint);
1763
1794
  send({
1764
1795
  type: "ZOOM",
@@ -1809,15 +1840,14 @@ const machine = createMachine({
1809
1840
  if (isSameSize(oldViewportRect, newViewportRect)) return;
1810
1841
  context.set("viewportRect", newViewportRect);
1811
1842
  const oldCrop = context.get("crop");
1812
- if (!isVisibleRect(oldViewportRect)) {
1813
- if (!isVisibleRect(oldCrop)) {
1814
- send({
1815
- type: "SET_DEFAULT_CROP",
1816
- src: "viewport-resize"
1817
- });
1818
- return;
1819
- }
1843
+ if (!isVisibleRect(oldCrop)) {
1844
+ send({
1845
+ type: "SET_DEFAULT_CROP",
1846
+ src: "viewport-resize"
1847
+ });
1848
+ return;
1820
1849
  }
1850
+ if (!isVisibleRect(oldViewportRect)) return;
1821
1851
  const aspectRatio = resolveCropAspectRatio(prop("cropShape"), prop("aspectRatio"));
1822
1852
  const { minSize, maxSize } = getCropSizeLimits(prop);
1823
1853
  const constrainedCrop = computeResizeCrop({
@@ -1840,12 +1870,42 @@ const machine = createMachine({
1840
1870
  height: constrainedCrop.height
1841
1871
  });
1842
1872
  },
1843
- resetToInitialState({ context }) {
1873
+ resetToInitialState({ context, send }) {
1844
1874
  context.set("zoom", context.initial("zoom"));
1845
1875
  context.set("rotation", context.initial("rotation"));
1846
1876
  context.set("flip", context.initial("flip"));
1847
1877
  context.set("offset", ZERO_POINT);
1848
- context.set("crop", context.initial("crop"));
1878
+ send({
1879
+ type: "SET_DEFAULT_CROP",
1880
+ src: "reset"
1881
+ });
1882
+ },
1883
+ adjustCropAspectRatio({ context, prop }) {
1884
+ const viewportRect = context.get("viewportRect");
1885
+ if (!isVisibleRect(viewportRect)) return;
1886
+ const crop = context.get("crop");
1887
+ if (!isVisibleRect(crop)) return;
1888
+ const aspectRatio = resolveCropAspectRatio(prop("cropShape"), prop("aspectRatio"));
1889
+ if (aspectRatio === void 0) return;
1890
+ if (isAspectRatioEqual(crop.width / crop.height, aspectRatio)) return;
1891
+ const { minSize, maxSize } = getCropSizeLimits(prop);
1892
+ const constrainedCrop = computeResizeCrop({
1893
+ cropStart: crop,
1894
+ handlePosition: "se",
1895
+ delta: ZERO_POINT,
1896
+ viewportRect,
1897
+ minSize,
1898
+ maxSize,
1899
+ aspectRatio
1900
+ });
1901
+ if (isSameSize(crop, constrainedCrop)) return;
1902
+ const pos = centerCropOnPoint(constrainedCrop, getCenterPoint(crop), viewportRect);
1903
+ context.set("crop", {
1904
+ x: pos.x,
1905
+ y: pos.y,
1906
+ width: constrainedCrop.width,
1907
+ height: constrainedCrop.height
1908
+ });
1849
1909
  }
1850
1910
  },
1851
1911
  effects: {
@@ -1855,7 +1915,8 @@ const machine = createMachine({
1855
1915
  type: "POINTER_MOVE",
1856
1916
  point: getEventPoint(event),
1857
1917
  target: getEventTarget(event),
1858
- shiftKey: event.shiftKey
1918
+ shiftKey: event.shiftKey,
1919
+ altKey: event.altKey
1859
1920
  });
1860
1921
  }
1861
1922
  function onPointerUp() {
@@ -1,13 +1,13 @@
1
1
  import { n as AnatomyInstance } from "../../create-anatomy-smWrirg1.cjs";
2
2
  import { r as CollectionOptions, t as CollectionItem } from "../../types-CADkcKtr.cjs";
3
- import { t as ListCollection } from "../../list-collection-BvMwDNHf.cjs";
4
- import { i as GridCollectionOptions, n as SelectionMode, r as GridCollection, t as Selection } from "../../selection-vng1guNc.cjs";
3
+ import { t as ListCollection } from "../../list-collection-DettiQL3.cjs";
4
+ import { i as GridCollectionOptions, n as SelectionMode, r as GridCollection, t as Selection } from "../../selection-D3b3yV_x.cjs";
5
5
  import { p as Machine, u as EventObject, y as Service } from "../../types-DejIu60O.cjs";
6
6
  import { b as NormalizeProps, g as RequiredBy, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-Bqw3r34-.cjs";
7
7
  import { n as TypeaheadState } from "../../typeahead-BdNwVP09.cjs";
8
8
 
9
9
  //#region src/machines/listbox/listbox.anatomy.d.ts
10
- declare const anatomy: AnatomyInstance<"root" | "label" | "valueText" | "input" | "item" | "content" | "itemText" | "itemIndicator" | "itemGroup" | "itemGroupLabel">;
10
+ declare const anatomy: AnatomyInstance<"root" | "label" | "item" | "input" | "itemIndicator" | "itemText" | "content" | "itemGroup" | "valueText" | "itemGroupLabel">;
11
11
  //#endregion
12
12
  //#region src/machines/listbox/listbox.collection.d.ts
13
13
  declare const collection: {
@@ -1,13 +1,13 @@
1
1
  import { n as AnatomyInstance } from "../../create-anatomy-DHVOqZET.mjs";
2
2
  import { r as CollectionOptions, t as CollectionItem } from "../../types-Df8ZhdY-.mjs";
3
- import { t as ListCollection } from "../../list-collection-CTt1eong.mjs";
4
- import { i as GridCollectionOptions, n as SelectionMode, r as GridCollection, t as Selection } from "../../selection-JDFmyke7.mjs";
3
+ import { t as ListCollection } from "../../list-collection-BbgocToA.mjs";
4
+ import { i as GridCollectionOptions, n as SelectionMode, r as GridCollection, t as Selection } from "../../selection-CTaapzrB.mjs";
5
5
  import { p as Machine, u as EventObject, y as Service } from "../../types-DL5AIQk5.mjs";
6
6
  import { b as NormalizeProps, g as RequiredBy, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-BuUzJjaP.mjs";
7
7
  import { n as TypeaheadState } from "../../typeahead-DMSwLv1e.mjs";
8
8
 
9
9
  //#region src/machines/listbox/listbox.anatomy.d.ts
10
- declare const anatomy: AnatomyInstance<"root" | "label" | "valueText" | "input" | "item" | "content" | "itemText" | "itemIndicator" | "itemGroup" | "itemGroupLabel">;
10
+ declare const anatomy: AnatomyInstance<"root" | "label" | "item" | "input" | "itemIndicator" | "itemText" | "content" | "itemGroup" | "valueText" | "itemGroupLabel">;
11
11
  //#endregion
12
12
  //#region src/machines/listbox/listbox.collection.d.ts
13
13
  declare const collection: {
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DejIu6
3
3
  import { b as NormalizeProps, d as Orientation, g as RequiredBy, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-Bqw3r34-.cjs";
4
4
 
5
5
  //#region src/machines/marquee/marquee.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "item" | "content" | "viewport" | "edge">;
6
+ declare const anatomy: AnatomyInstance<"root" | "item" | "viewport" | "content" | "edge">;
7
7
  //#endregion
8
8
  //#region src/machines/marquee/marquee.types.d.ts
9
9
  interface PauseStatusDetails {
@@ -96,7 +96,7 @@ declare function connect<T extends PropTypes>(service: MarqueeService, normalize
96
96
  declare const machine: Machine<MarqueeSchema>;
97
97
  //#endregion
98
98
  //#region src/machines/marquee/marquee.props.d.ts
99
- declare const props: ("ids" | "id" | "getRootNode" | "paused" | "onComplete" | ("dir" | "reverse" | "translations" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete")[];
100
- declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "ids" | "id" | "getRootNode" | "paused" | "onComplete" | ("dir" | "reverse" | "translations" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete">];
99
+ declare const props: ("ids" | "id" | "getRootNode" | "onComplete" | "paused" | ("translations" | "dir" | "reverse" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete")[];
100
+ declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "ids" | "id" | "getRootNode" | "onComplete" | "paused" | ("translations" | "dir" | "reverse" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete">];
101
101
  //#endregion
102
102
  export { type MarqueeApi as Api, type ContentProps, type DimensionSnapshot, type EdgeProps, type ElementIds, type IntlTranslations, type MarqueeMachine as Machine, type Orientation, type PauseStatusDetails, type MarqueeProps as Props, type MarqueeService as Service, type Side, type UserDefinedContext, anatomy, connect, machine, props, splitProps };
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DL5AIQ
3
3
  import { b as NormalizeProps, d as Orientation, g as RequiredBy, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-BuUzJjaP.mjs";
4
4
 
5
5
  //#region src/machines/marquee/marquee.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "item" | "content" | "viewport" | "edge">;
6
+ declare const anatomy: AnatomyInstance<"root" | "item" | "viewport" | "content" | "edge">;
7
7
  //#endregion
8
8
  //#region src/machines/marquee/marquee.types.d.ts
9
9
  interface PauseStatusDetails {
@@ -96,7 +96,7 @@ declare function connect<T extends PropTypes>(service: MarqueeService, normalize
96
96
  declare const machine: Machine<MarqueeSchema>;
97
97
  //#endregion
98
98
  //#region src/machines/marquee/marquee.props.d.ts
99
- declare const props: ("ids" | "id" | "getRootNode" | "paused" | "onComplete" | ("dir" | "reverse" | "translations" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete")[];
100
- declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "ids" | "id" | "getRootNode" | "paused" | "onComplete" | ("dir" | "reverse" | "translations" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete">];
99
+ declare const props: ("ids" | "id" | "getRootNode" | "onComplete" | "paused" | ("translations" | "dir" | "reverse" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete")[];
100
+ declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "ids" | "id" | "getRootNode" | "onComplete" | "paused" | ("translations" | "dir" | "reverse" | "spacing" | "side" | "speed" | "delay" | "loopCount" | "autoFill" | "pauseOnInteraction" | "defaultPaused") | "onPauseChange" | "onLoopComplete">];
101
101
  //#endregion
102
102
  export { type MarqueeApi as Api, type ContentProps, type DimensionSnapshot, type EdgeProps, type ElementIds, type IntlTranslations, type MarqueeMachine as Machine, type Orientation, type PauseStatusDetails, type MarqueeProps as Props, type MarqueeService as Service, type Side, type UserDefinedContext, anatomy, connect, machine, props, splitProps };
@@ -8,7 +8,7 @@ import { c as Placement, d as PositioningOptions } from "../../types-D5ziaMrd.cj
8
8
  import { a as Point } from "../../types-DddL75YY.cjs";
9
9
 
10
10
  //#region src/machines/menu/menu.anatomy.d.ts
11
- declare const anatomy: AnatomyInstance<"indicator" | "item" | "trigger" | "separator" | "content" | "itemText" | "itemIndicator" | "arrow" | "positioner" | "arrowTip" | "itemGroup" | "itemGroupLabel" | "contextTrigger" | "triggerItem">;
11
+ declare const anatomy: AnatomyInstance<"item" | "itemIndicator" | "itemText" | "separator" | "trigger" | "content" | "indicator" | "itemGroup" | "arrow" | "arrowTip" | "positioner" | "itemGroupLabel" | "contextTrigger" | "triggerItem">;
12
12
  //#endregion
13
13
  //#region src/machines/menu/menu.types.d.ts
14
14
  interface OpenChangeDetails {
@@ -8,7 +8,7 @@ import { p as PositioningOptions, u as Placement } from "../../index-BTi1wETB.mj
8
8
  import { a as Point } from "../../types-J14X3oxU.mjs";
9
9
 
10
10
  //#region src/machines/menu/menu.anatomy.d.ts
11
- declare const anatomy: AnatomyInstance<"indicator" | "item" | "trigger" | "separator" | "content" | "itemText" | "itemIndicator" | "arrow" | "positioner" | "arrowTip" | "itemGroup" | "itemGroupLabel" | "contextTrigger" | "triggerItem">;
11
+ declare const anatomy: AnatomyInstance<"item" | "itemIndicator" | "itemText" | "separator" | "trigger" | "content" | "indicator" | "itemGroup" | "arrow" | "arrowTip" | "positioner" | "itemGroupLabel" | "contextTrigger" | "triggerItem">;
12
12
  //#endregion
13
13
  //#region src/machines/menu/menu.types.d.ts
14
14
  interface OpenChangeDetails {
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DejIu6
3
3
  import { _ as Size, b as NormalizeProps, d as Orientation, f as OrientationProperty, g as RequiredBy, m as Rect, p as Point, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-Bqw3r34-.cjs";
4
4
 
5
5
  //#region src/machines/navigation-menu/navigation-menu.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "link" | "indicator" | "list" | "item" | "trigger" | "content" | "viewport" | "viewportPositioner" | "itemIndicator" | "arrow">;
6
+ declare const anatomy: AnatomyInstance<"root" | "item" | "viewport" | "itemIndicator" | "trigger" | "content" | "indicator" | "link" | "arrow" | "list" | "viewportPositioner">;
7
7
  //#endregion
8
8
  //#region src/machines/navigation-menu/navigation-menu.types.d.ts
9
9
  interface ValueChangeDetails {
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DL5AIQ
3
3
  import { _ as Size, b as NormalizeProps, d as Orientation, f as OrientationProperty, g as RequiredBy, m as Rect, p as Point, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-BuUzJjaP.mjs";
4
4
 
5
5
  //#region src/machines/navigation-menu/navigation-menu.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "link" | "indicator" | "list" | "item" | "trigger" | "content" | "viewport" | "viewportPositioner" | "itemIndicator" | "arrow">;
6
+ declare const anatomy: AnatomyInstance<"root" | "item" | "viewport" | "itemIndicator" | "trigger" | "content" | "indicator" | "link" | "arrow" | "list" | "viewportPositioner">;
7
7
  //#endregion
8
8
  //#region src/machines/navigation-menu/navigation-menu.types.d.ts
9
9
  interface ValueChangeDetails {
@@ -4,7 +4,7 @@ import { b as NormalizeProps, g as RequiredBy, o as LocaleProperties, t as Commo
4
4
  import { NumberFormatter, NumberParser } from "@internationalized/number";
5
5
 
6
6
  //#region src/machines/number-input/number-input.anatomy.d.ts
7
- declare const anatomy: AnatomyInstance<"root" | "label" | "valueText" | "control" | "input" | "incrementTrigger" | "decrementTrigger" | "scrubber">;
7
+ declare const anatomy: AnatomyInstance<"root" | "label" | "control" | "input" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber">;
8
8
  //#endregion
9
9
  //#region src/machines/number-input/number-input.types.d.ts
10
10
  interface ValueChangeDetails {
@@ -4,7 +4,7 @@ import { b as NormalizeProps, g as RequiredBy, o as LocaleProperties, t as Commo
4
4
  import { NumberFormatter, NumberParser } from "@internationalized/number";
5
5
 
6
6
  //#region src/machines/number-input/number-input.anatomy.d.ts
7
- declare const anatomy: AnatomyInstance<"root" | "label" | "valueText" | "control" | "input" | "incrementTrigger" | "decrementTrigger" | "scrubber">;
7
+ declare const anatomy: AnatomyInstance<"root" | "label" | "control" | "input" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber">;
8
8
  //#endregion
9
9
  //#region src/machines/number-input/number-input.types.d.ts
10
10
  interface ValueChangeDetails {
@@ -3,7 +3,7 @@ import { p as Machine, u as EventObject, y as Service } from "../../types-DejIu6
3
3
  import { b as NormalizeProps, g as RequiredBy, r as DirectionProperty, t as CommonProperties, x as PropTypes } from "../../index-Bqw3r34-.cjs";
4
4
 
5
5
  //#region src/machines/pagination/pagination.anatomy.d.ts
6
- declare const anatomy: AnatomyInstance<"root" | "item" | "nextTrigger" | "prevTrigger" | "ellipsis" | "firstTrigger" | "lastTrigger">;
6
+ declare const anatomy: AnatomyInstance<"root" | "item" | "ellipsis" | "firstTrigger" | "prevTrigger" | "nextTrigger" | "lastTrigger">;
7
7
  //#endregion
8
8
  //#region src/machines/pagination/pagination.types.d.ts
9
9
  interface PageChangeDetails {