made-refine 0.2.7 → 0.2.9

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/utils.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/utils/css-value.ts
2
2
  function parsePropertyValue(value) {
3
3
  const raw = value.trim();
4
- const match = raw.match(/^(-?\d*\.?\d+)(px|rem|em|%)?$/);
4
+ const match = raw.match(/^(-?\d*\.?\d+)(px|rem|em|vh|vw|%)?$/);
5
5
  if (match) {
6
6
  return {
7
7
  numericValue: parseFloat(match[1]),
@@ -22,6 +22,24 @@ function formatPropertyValue(value) {
22
22
  return `${value.numericValue}${value.unit}`;
23
23
  }
24
24
 
25
+ // src/canvas-store.ts
26
+ import { useSyncExternalStore } from "react";
27
+ var DEFAULT = { active: false, zoom: 1, panX: 0, panY: 0 };
28
+ var snapshot = DEFAULT;
29
+ var bodyOffset = { x: 0, y: 0 };
30
+ function getBodyOffset() {
31
+ return bodyOffset;
32
+ }
33
+ function getCanvasSnapshot() {
34
+ return snapshot;
35
+ }
36
+
37
+ // src/utils/measurements.ts
38
+ function getZoomScale() {
39
+ const snap = getCanvasSnapshot();
40
+ return snap.active ? snap.zoom : 1;
41
+ }
42
+
25
43
  // src/utils.ts
26
44
  function clamp(value, min, max) {
27
45
  if (!Number.isFinite(value)) return min;
@@ -119,6 +137,7 @@ var ORIGINAL_STYLE_PROPS = [
119
137
  "width",
120
138
  "height",
121
139
  "background-color",
140
+ "background",
122
141
  "color",
123
142
  "border-color",
124
143
  "outline-color",
@@ -501,7 +520,7 @@ function hasDirectNonWhitespaceText(element) {
501
520
  (node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
502
521
  );
503
522
  }
504
- function isTextElement(element) {
523
+ function isTextElement2(element) {
505
524
  const tagName = element.tagName.toLowerCase();
506
525
  if (TEXT_ELEMENT_TAGS.has(tagName)) {
507
526
  return true;
@@ -720,6 +739,55 @@ function parseColorValue(cssValue) {
720
739
  return parseNamedColor(raw);
721
740
  }
722
741
  var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
742
+ function isVisibleBorderSide(side) {
743
+ return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
744
+ }
745
+ function hasVisibleOutline(computed) {
746
+ return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
747
+ }
748
+ function parseVisibleColor(value, fallbackCurrentColor) {
749
+ const raw = value.trim();
750
+ const lowered = raw.toLowerCase();
751
+ if (!raw || lowered === "none" || lowered === "transparent") {
752
+ return null;
753
+ }
754
+ const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
755
+ const parsed = parseColorValue(resolved);
756
+ if (parsed.alpha <= 0) {
757
+ return null;
758
+ }
759
+ return parsed;
760
+ }
761
+ function addUniqueColor(colors, color) {
762
+ if (!color) return;
763
+ colors.set(`${color.hex}:${color.alpha}`, color);
764
+ }
765
+ function isTextRenderingFormControl(element) {
766
+ if (element instanceof HTMLTextAreaElement) return true;
767
+ if (element instanceof HTMLSelectElement) return true;
768
+ if (element instanceof HTMLButtonElement) return true;
769
+ if (element instanceof HTMLInputElement) {
770
+ const textlessInputTypes = /* @__PURE__ */ new Set([
771
+ "hidden",
772
+ "checkbox",
773
+ "radio",
774
+ "range",
775
+ "color",
776
+ "file",
777
+ "image"
778
+ ]);
779
+ return !textlessInputTypes.has(element.type.toLowerCase());
780
+ }
781
+ return false;
782
+ }
783
+ function hasRenderableTextNode(element) {
784
+ if (element.isContentEditable) return true;
785
+ if (isTextRenderingFormControl(element)) return true;
786
+ if (!element.textContent?.trim()) return false;
787
+ if (hasDirectNonWhitespaceText(element)) return true;
788
+ const tagName = element.tagName.toLowerCase();
789
+ return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
790
+ }
723
791
  function getComputedBoxShadow(element) {
724
792
  const computed = window.getComputedStyle(element);
725
793
  const value = computed.boxShadow.trim();
@@ -733,11 +801,9 @@ function getComputedColorStyles(element) {
733
801
  { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
734
802
  { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
735
803
  ];
736
- const visibleBorderSide = borderSides.find(
737
- (side) => side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0
738
- );
804
+ const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
739
805
  const hasBorder = Boolean(visibleBorderSide);
740
- const hasOutline = computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
806
+ const hasOutline = hasVisibleOutline(computed);
741
807
  return {
742
808
  backgroundColor: parseColorValue(computed.backgroundColor),
743
809
  color: parseColorValue(computed.color),
@@ -745,6 +811,48 @@ function getComputedColorStyles(element) {
745
811
  outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
746
812
  };
747
813
  }
814
+ function getSelectionColors(element) {
815
+ const uniqueColors = /* @__PURE__ */ new Map();
816
+ const queue = [element];
817
+ for (let index = 0; index < queue.length; index++) {
818
+ const node = queue[index];
819
+ const computed = window.getComputedStyle(node);
820
+ if (computed.display === "none") {
821
+ continue;
822
+ }
823
+ const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
824
+ const currentTextColor = computed.color;
825
+ if (!isVisibilityHidden) {
826
+ addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
827
+ if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
828
+ addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
829
+ }
830
+ const borderSides = [
831
+ { style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
832
+ { style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
833
+ { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
834
+ { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
835
+ ];
836
+ for (const side of borderSides) {
837
+ if (!isVisibleBorderSide(side)) continue;
838
+ addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
839
+ }
840
+ if (hasVisibleOutline(computed)) {
841
+ addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
842
+ }
843
+ if (node instanceof SVGElement) {
844
+ const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
845
+ const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
846
+ addUniqueColor(uniqueColors, fillColor);
847
+ addUniqueColor(uniqueColors, strokeColor);
848
+ }
849
+ }
850
+ for (const child of node.children) {
851
+ queue.push(child);
852
+ }
853
+ }
854
+ return Array.from(uniqueColors.values());
855
+ }
748
856
  function getAllComputedStyles(element) {
749
857
  const { spacing, borderRadius, flex } = getComputedStyles(element);
750
858
  return {
@@ -792,7 +900,7 @@ function getElementInfo(element) {
792
900
  classList: Array.from(element.classList),
793
901
  isFlexContainer: isFlexContainer2,
794
902
  isFlexItem,
795
- isTextElement: isTextElement(element),
903
+ isTextElement: isTextElement2(element),
796
904
  parentElement,
797
905
  hasChildren: element.children.length > 0
798
906
  };
@@ -832,9 +940,8 @@ function isFitSizing(element, dimension) {
832
940
  return false;
833
941
  }
834
942
  function getDimensionDisplay(element) {
835
- const rect = element.getBoundingClientRect();
836
- const width = Math.round(rect.width);
837
- const height = Math.round(rect.height);
943
+ const width = Math.round(element.offsetWidth);
944
+ const height = Math.round(element.offsetHeight);
838
945
  const widthIsFit = isFitSizing(element, "width");
839
946
  const heightIsFit = isFitSizing(element, "height");
840
947
  return {
@@ -867,8 +974,9 @@ function calculateParentMeasurements(element, container) {
867
974
  parentInnerRight = paddingBoxRight - (parseFloat(parentStyles.paddingRight) || 0);
868
975
  parentInnerBottom = paddingBoxBottom - (parseFloat(parentStyles.paddingBottom) || 0);
869
976
  }
977
+ const zoom = getZoomScale();
870
978
  const measurements = [];
871
- const topDistance = Math.round(elementRect.top - parentInnerTop);
979
+ const topDistance = Math.round((elementRect.top - parentInnerTop) / zoom);
872
980
  if (topDistance > 0) {
873
981
  const midX = elementRect.left + elementRect.width / 2;
874
982
  measurements.push({
@@ -881,7 +989,7 @@ function calculateParentMeasurements(element, container) {
881
989
  labelPosition: { x: midX, y: (parentInnerTop + elementRect.top) / 2 }
882
990
  });
883
991
  }
884
- const bottomDistance = Math.round(parentInnerBottom - elementRect.bottom);
992
+ const bottomDistance = Math.round((parentInnerBottom - elementRect.bottom) / zoom);
885
993
  if (bottomDistance > 0) {
886
994
  const midX = elementRect.left + elementRect.width / 2;
887
995
  measurements.push({
@@ -894,7 +1002,7 @@ function calculateParentMeasurements(element, container) {
894
1002
  labelPosition: { x: midX, y: (elementRect.bottom + parentInnerBottom) / 2 }
895
1003
  });
896
1004
  }
897
- const leftDistance = Math.round(elementRect.left - parentInnerLeft);
1005
+ const leftDistance = Math.round((elementRect.left - parentInnerLeft) / zoom);
898
1006
  if (leftDistance > 0) {
899
1007
  const midY = elementRect.top + elementRect.height / 2;
900
1008
  measurements.push({
@@ -907,7 +1015,7 @@ function calculateParentMeasurements(element, container) {
907
1015
  labelPosition: { x: (parentInnerLeft + elementRect.left) / 2, y: midY }
908
1016
  });
909
1017
  }
910
- const rightDistance = Math.round(parentInnerRight - elementRect.right);
1018
+ const rightDistance = Math.round((parentInnerRight - elementRect.right) / zoom);
911
1019
  if (rightDistance > 0) {
912
1020
  const midY = elementRect.top + elementRect.height / 2;
913
1021
  measurements.push({
@@ -925,6 +1033,7 @@ function calculateParentMeasurements(element, container) {
925
1033
  function calculateElementMeasurements(from, to) {
926
1034
  const fromRect = from.getBoundingClientRect();
927
1035
  const toRect = to.getBoundingClientRect();
1036
+ const zoom = getZoomScale();
928
1037
  const measurements = [];
929
1038
  const horizontalOverlap = fromRect.left < toRect.right && fromRect.right > toRect.left;
930
1039
  const verticalOverlap = fromRect.top < toRect.bottom && fromRect.bottom > toRect.top;
@@ -933,7 +1042,7 @@ function calculateElementMeasurements(from, to) {
933
1042
  const overlapBottom = Math.min(fromRect.bottom, toRect.bottom);
934
1043
  const midY = (overlapTop + overlapBottom) / 2;
935
1044
  if (fromRect.right <= toRect.left) {
936
- const distance = Math.round(toRect.left - fromRect.right);
1045
+ const distance = Math.round((toRect.left - fromRect.right) / zoom);
937
1046
  measurements.push({
938
1047
  direction: "horizontal",
939
1048
  x1: fromRect.right,
@@ -944,7 +1053,7 @@ function calculateElementMeasurements(from, to) {
944
1053
  labelPosition: { x: (fromRect.right + toRect.left) / 2, y: midY }
945
1054
  });
946
1055
  } else if (fromRect.left >= toRect.right) {
947
- const distance = Math.round(fromRect.left - toRect.right);
1056
+ const distance = Math.round((fromRect.left - toRect.right) / zoom);
948
1057
  measurements.push({
949
1058
  direction: "horizontal",
950
1059
  x1: toRect.right,
@@ -961,7 +1070,7 @@ function calculateElementMeasurements(from, to) {
961
1070
  const overlapRight = Math.min(fromRect.right, toRect.right);
962
1071
  const midX = (overlapLeft + overlapRight) / 2;
963
1072
  if (fromRect.bottom <= toRect.top) {
964
- const distance = Math.round(toRect.top - fromRect.bottom);
1073
+ const distance = Math.round((toRect.top - fromRect.bottom) / zoom);
965
1074
  measurements.push({
966
1075
  direction: "vertical",
967
1076
  x1: midX,
@@ -972,7 +1081,7 @@ function calculateElementMeasurements(from, to) {
972
1081
  labelPosition: { x: midX, y: (fromRect.bottom + toRect.top) / 2 }
973
1082
  });
974
1083
  } else if (fromRect.top >= toRect.bottom) {
975
- const distance = Math.round(fromRect.top - toRect.bottom);
1084
+ const distance = Math.round((fromRect.top - toRect.bottom) / zoom);
976
1085
  measurements.push({
977
1086
  direction: "vertical",
978
1087
  x1: midX,
@@ -989,7 +1098,7 @@ function calculateElementMeasurements(from, to) {
989
1098
  const fromCenterY = fromRect.top + fromRect.height / 2;
990
1099
  const toCenterX = toRect.left + toRect.width / 2;
991
1100
  const toCenterY = toRect.top + toRect.height / 2;
992
- const hDistance = toCenterX > fromCenterX ? Math.round(toRect.left - fromRect.right) : Math.round(fromRect.left - toRect.right);
1101
+ const hDistance = toCenterX > fromCenterX ? Math.round((toRect.left - fromRect.right) / zoom) : Math.round((fromRect.left - toRect.right) / zoom);
993
1102
  if (hDistance > 0) {
994
1103
  const startX = toCenterX > fromCenterX ? fromRect.right : fromRect.left;
995
1104
  const endX = toCenterX > fromCenterX ? toRect.left : toRect.right;
@@ -1004,7 +1113,7 @@ function calculateElementMeasurements(from, to) {
1004
1113
  labelPosition: { x: (startX + endX) / 2, y }
1005
1114
  });
1006
1115
  }
1007
- const vDistance = toCenterY > fromCenterY ? Math.round(toRect.top - fromRect.bottom) : Math.round(fromRect.top - toRect.bottom);
1116
+ const vDistance = toCenterY > fromCenterY ? Math.round((toRect.top - fromRect.bottom) / zoom) : Math.round((fromRect.top - toRect.bottom) / zoom);
1008
1117
  if (vDistance > 0) {
1009
1118
  const x = (fromCenterX + toCenterX) / 2;
1010
1119
  const startY = toCenterY > fromCenterY ? fromRect.bottom : fromRect.top;
@@ -1025,70 +1134,77 @@ function calculateElementMeasurements(from, to) {
1025
1134
  var GUIDELINE_PROXIMITY = 80;
1026
1135
  function calculateGuidelineMeasurements(element, guidelines, mousePosition) {
1027
1136
  if (guidelines.length === 0) return [];
1137
+ const snap = getCanvasSnapshot();
1138
+ const zoom = snap.active ? snap.zoom : 1;
1028
1139
  const rect = element.getBoundingClientRect();
1029
- const scrollX = window.scrollX;
1030
- const scrollY = window.scrollY;
1031
1140
  const measurements = [];
1032
1141
  for (const g of guidelines) {
1142
+ let viewportPos;
1143
+ if (snap.active) {
1144
+ const pan = g.orientation === "horizontal" ? snap.panY : snap.panX;
1145
+ const bo = g.orientation === "horizontal" ? getBodyOffset().y : getBodyOffset().x;
1146
+ viewportPos = bo + (g.position - bo + pan) * zoom;
1147
+ } else {
1148
+ const scroll = g.orientation === "horizontal" ? window.scrollY : window.scrollX;
1149
+ viewportPos = g.position - scroll;
1150
+ }
1033
1151
  if (g.orientation === "horizontal") {
1034
- const gy = g.position - scrollY;
1035
1152
  const midX = rect.left + rect.width / 2;
1036
- if (mousePosition && Math.abs(mousePosition.y - gy) > GUIDELINE_PROXIMITY) continue;
1037
- if (gy < rect.top) {
1038
- const distance = Math.round(rect.top - gy);
1153
+ if (mousePosition && Math.abs(mousePosition.y - viewportPos) > GUIDELINE_PROXIMITY) continue;
1154
+ if (viewportPos < rect.top) {
1155
+ const distance = Math.round((rect.top - viewportPos) / zoom);
1039
1156
  if (distance > 0) {
1040
1157
  measurements.push({
1041
1158
  direction: "vertical",
1042
1159
  x1: midX,
1043
- y1: gy,
1160
+ y1: viewportPos,
1044
1161
  x2: midX,
1045
1162
  y2: rect.top,
1046
1163
  distance,
1047
- labelPosition: { x: midX, y: (gy + rect.top) / 2 }
1164
+ labelPosition: { x: midX, y: (viewportPos + rect.top) / 2 }
1048
1165
  });
1049
1166
  }
1050
- } else if (gy > rect.bottom) {
1051
- const distance = Math.round(gy - rect.bottom);
1167
+ } else if (viewportPos > rect.bottom) {
1168
+ const distance = Math.round((viewportPos - rect.bottom) / zoom);
1052
1169
  if (distance > 0) {
1053
1170
  measurements.push({
1054
1171
  direction: "vertical",
1055
1172
  x1: midX,
1056
1173
  y1: rect.bottom,
1057
1174
  x2: midX,
1058
- y2: gy,
1175
+ y2: viewportPos,
1059
1176
  distance,
1060
- labelPosition: { x: midX, y: (rect.bottom + gy) / 2 }
1177
+ labelPosition: { x: midX, y: (rect.bottom + viewportPos) / 2 }
1061
1178
  });
1062
1179
  }
1063
1180
  }
1064
1181
  } else {
1065
- const gx = g.position - scrollX;
1066
1182
  const midY = rect.top + rect.height / 2;
1067
- if (mousePosition && Math.abs(mousePosition.x - gx) > GUIDELINE_PROXIMITY) continue;
1068
- if (gx < rect.left) {
1069
- const distance = Math.round(rect.left - gx);
1183
+ if (mousePosition && Math.abs(mousePosition.x - viewportPos) > GUIDELINE_PROXIMITY) continue;
1184
+ if (viewportPos < rect.left) {
1185
+ const distance = Math.round((rect.left - viewportPos) / zoom);
1070
1186
  if (distance > 0) {
1071
1187
  measurements.push({
1072
1188
  direction: "horizontal",
1073
- x1: gx,
1189
+ x1: viewportPos,
1074
1190
  y1: midY,
1075
1191
  x2: rect.left,
1076
1192
  y2: midY,
1077
1193
  distance,
1078
- labelPosition: { x: (gx + rect.left) / 2, y: midY }
1194
+ labelPosition: { x: (viewportPos + rect.left) / 2, y: midY }
1079
1195
  });
1080
1196
  }
1081
- } else if (gx > rect.right) {
1082
- const distance = Math.round(gx - rect.right);
1197
+ } else if (viewportPos > rect.right) {
1198
+ const distance = Math.round((viewportPos - rect.right) / zoom);
1083
1199
  if (distance > 0) {
1084
1200
  measurements.push({
1085
1201
  direction: "horizontal",
1086
1202
  x1: rect.right,
1087
1203
  y1: midY,
1088
- x2: gx,
1204
+ x2: viewportPos,
1089
1205
  y2: midY,
1090
1206
  distance,
1091
- labelPosition: { x: (rect.right + gx) / 2, y: midY }
1207
+ labelPosition: { x: (rect.right + viewportPos) / 2, y: midY }
1092
1208
  });
1093
1209
  }
1094
1210
  }
@@ -2466,7 +2582,7 @@ function inferLayoutPrescription(edit, operation, reasons) {
2466
2582
  anchorLabel: formatAnchorRef(anchor)
2467
2583
  };
2468
2584
  });
2469
- const subjectSnapshot = childSnapshots.find((snapshot) => snapshot.child === edit.element);
2585
+ const subjectSnapshot = childSnapshots.find((snapshot2) => snapshot2.child === edit.element);
2470
2586
  const subjectRect = edit.element.getBoundingClientRect();
2471
2587
  const subjectCenterX = subjectRect.left + subjectRect.width / 2;
2472
2588
  const subjectCenterY = subjectRect.top + subjectRect.height / 2;
@@ -2868,12 +2984,13 @@ export {
2868
2984
  getFlexDirection,
2869
2985
  getMoveIntentForEdit,
2870
2986
  getOriginalInlineStyles,
2987
+ getSelectionColors,
2871
2988
  getSizingValue,
2872
2989
  isFlexContainer,
2873
2990
  isInFlowChild,
2874
2991
  isInputFocused,
2875
2992
  isLayoutContainer,
2876
- isTextElement,
2993
+ isTextElement2 as isTextElement,
2877
2994
  parseColorValue,
2878
2995
  parsePropertyValue,
2879
2996
  propertyToCSSMap,