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.js CHANGED
@@ -69,12 +69,13 @@ __export(utils_exports, {
69
69
  getFlexDirection: () => getFlexDirection,
70
70
  getMoveIntentForEdit: () => getMoveIntentForEdit,
71
71
  getOriginalInlineStyles: () => getOriginalInlineStyles,
72
+ getSelectionColors: () => getSelectionColors,
72
73
  getSizingValue: () => getSizingValue,
73
74
  isFlexContainer: () => isFlexContainer,
74
75
  isInFlowChild: () => isInFlowChild,
75
76
  isInputFocused: () => isInputFocused,
76
77
  isLayoutContainer: () => isLayoutContainer,
77
- isTextElement: () => isTextElement,
78
+ isTextElement: () => isTextElement2,
78
79
  parseColorValue: () => parseColorValue,
79
80
  parsePropertyValue: () => parsePropertyValue,
80
81
  propertyToCSSMap: () => propertyToCSSMap,
@@ -90,7 +91,7 @@ module.exports = __toCommonJS(utils_exports);
90
91
  // src/utils/css-value.ts
91
92
  function parsePropertyValue(value) {
92
93
  const raw = value.trim();
93
- const match = raw.match(/^(-?\d*\.?\d+)(px|rem|em|%)?$/);
94
+ const match = raw.match(/^(-?\d*\.?\d+)(px|rem|em|vh|vw|%)?$/);
94
95
  if (match) {
95
96
  return {
96
97
  numericValue: parseFloat(match[1]),
@@ -111,6 +112,24 @@ function formatPropertyValue(value) {
111
112
  return `${value.numericValue}${value.unit}`;
112
113
  }
113
114
 
115
+ // src/canvas-store.ts
116
+ var import_react = require("react");
117
+ var DEFAULT = { active: false, zoom: 1, panX: 0, panY: 0 };
118
+ var snapshot = DEFAULT;
119
+ var bodyOffset = { x: 0, y: 0 };
120
+ function getBodyOffset() {
121
+ return bodyOffset;
122
+ }
123
+ function getCanvasSnapshot() {
124
+ return snapshot;
125
+ }
126
+
127
+ // src/utils/measurements.ts
128
+ function getZoomScale() {
129
+ const snap = getCanvasSnapshot();
130
+ return snap.active ? snap.zoom : 1;
131
+ }
132
+
114
133
  // src/utils.ts
115
134
  function clamp(value, min, max) {
116
135
  if (!Number.isFinite(value)) return min;
@@ -208,6 +227,7 @@ var ORIGINAL_STYLE_PROPS = [
208
227
  "width",
209
228
  "height",
210
229
  "background-color",
230
+ "background",
211
231
  "color",
212
232
  "border-color",
213
233
  "outline-color",
@@ -590,7 +610,7 @@ function hasDirectNonWhitespaceText(element) {
590
610
  (node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
591
611
  );
592
612
  }
593
- function isTextElement(element) {
613
+ function isTextElement2(element) {
594
614
  const tagName = element.tagName.toLowerCase();
595
615
  if (TEXT_ELEMENT_TAGS.has(tagName)) {
596
616
  return true;
@@ -809,6 +829,55 @@ function parseColorValue(cssValue) {
809
829
  return parseNamedColor(raw);
810
830
  }
811
831
  var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
832
+ function isVisibleBorderSide(side) {
833
+ return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
834
+ }
835
+ function hasVisibleOutline(computed) {
836
+ return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
837
+ }
838
+ function parseVisibleColor(value, fallbackCurrentColor) {
839
+ const raw = value.trim();
840
+ const lowered = raw.toLowerCase();
841
+ if (!raw || lowered === "none" || lowered === "transparent") {
842
+ return null;
843
+ }
844
+ const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
845
+ const parsed = parseColorValue(resolved);
846
+ if (parsed.alpha <= 0) {
847
+ return null;
848
+ }
849
+ return parsed;
850
+ }
851
+ function addUniqueColor(colors, color) {
852
+ if (!color) return;
853
+ colors.set(`${color.hex}:${color.alpha}`, color);
854
+ }
855
+ function isTextRenderingFormControl(element) {
856
+ if (element instanceof HTMLTextAreaElement) return true;
857
+ if (element instanceof HTMLSelectElement) return true;
858
+ if (element instanceof HTMLButtonElement) return true;
859
+ if (element instanceof HTMLInputElement) {
860
+ const textlessInputTypes = /* @__PURE__ */ new Set([
861
+ "hidden",
862
+ "checkbox",
863
+ "radio",
864
+ "range",
865
+ "color",
866
+ "file",
867
+ "image"
868
+ ]);
869
+ return !textlessInputTypes.has(element.type.toLowerCase());
870
+ }
871
+ return false;
872
+ }
873
+ function hasRenderableTextNode(element) {
874
+ if (element.isContentEditable) return true;
875
+ if (isTextRenderingFormControl(element)) return true;
876
+ if (!element.textContent?.trim()) return false;
877
+ if (hasDirectNonWhitespaceText(element)) return true;
878
+ const tagName = element.tagName.toLowerCase();
879
+ return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
880
+ }
812
881
  function getComputedBoxShadow(element) {
813
882
  const computed = window.getComputedStyle(element);
814
883
  const value = computed.boxShadow.trim();
@@ -822,11 +891,9 @@ function getComputedColorStyles(element) {
822
891
  { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
823
892
  { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
824
893
  ];
825
- const visibleBorderSide = borderSides.find(
826
- (side) => side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0
827
- );
894
+ const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
828
895
  const hasBorder = Boolean(visibleBorderSide);
829
- const hasOutline = computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
896
+ const hasOutline = hasVisibleOutline(computed);
830
897
  return {
831
898
  backgroundColor: parseColorValue(computed.backgroundColor),
832
899
  color: parseColorValue(computed.color),
@@ -834,6 +901,48 @@ function getComputedColorStyles(element) {
834
901
  outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
835
902
  };
836
903
  }
904
+ function getSelectionColors(element) {
905
+ const uniqueColors = /* @__PURE__ */ new Map();
906
+ const queue = [element];
907
+ for (let index = 0; index < queue.length; index++) {
908
+ const node = queue[index];
909
+ const computed = window.getComputedStyle(node);
910
+ if (computed.display === "none") {
911
+ continue;
912
+ }
913
+ const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
914
+ const currentTextColor = computed.color;
915
+ if (!isVisibilityHidden) {
916
+ addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
917
+ if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
918
+ addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
919
+ }
920
+ const borderSides = [
921
+ { style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
922
+ { style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
923
+ { style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
924
+ { style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
925
+ ];
926
+ for (const side of borderSides) {
927
+ if (!isVisibleBorderSide(side)) continue;
928
+ addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
929
+ }
930
+ if (hasVisibleOutline(computed)) {
931
+ addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
932
+ }
933
+ if (node instanceof SVGElement) {
934
+ const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
935
+ const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
936
+ addUniqueColor(uniqueColors, fillColor);
937
+ addUniqueColor(uniqueColors, strokeColor);
938
+ }
939
+ }
940
+ for (const child of node.children) {
941
+ queue.push(child);
942
+ }
943
+ }
944
+ return Array.from(uniqueColors.values());
945
+ }
837
946
  function getAllComputedStyles(element) {
838
947
  const { spacing, borderRadius, flex } = getComputedStyles(element);
839
948
  return {
@@ -881,7 +990,7 @@ function getElementInfo(element) {
881
990
  classList: Array.from(element.classList),
882
991
  isFlexContainer: isFlexContainer2,
883
992
  isFlexItem,
884
- isTextElement: isTextElement(element),
993
+ isTextElement: isTextElement2(element),
885
994
  parentElement,
886
995
  hasChildren: element.children.length > 0
887
996
  };
@@ -921,9 +1030,8 @@ function isFitSizing(element, dimension) {
921
1030
  return false;
922
1031
  }
923
1032
  function getDimensionDisplay(element) {
924
- const rect = element.getBoundingClientRect();
925
- const width = Math.round(rect.width);
926
- const height = Math.round(rect.height);
1033
+ const width = Math.round(element.offsetWidth);
1034
+ const height = Math.round(element.offsetHeight);
927
1035
  const widthIsFit = isFitSizing(element, "width");
928
1036
  const heightIsFit = isFitSizing(element, "height");
929
1037
  return {
@@ -956,8 +1064,9 @@ function calculateParentMeasurements(element, container) {
956
1064
  parentInnerRight = paddingBoxRight - (parseFloat(parentStyles.paddingRight) || 0);
957
1065
  parentInnerBottom = paddingBoxBottom - (parseFloat(parentStyles.paddingBottom) || 0);
958
1066
  }
1067
+ const zoom = getZoomScale();
959
1068
  const measurements = [];
960
- const topDistance = Math.round(elementRect.top - parentInnerTop);
1069
+ const topDistance = Math.round((elementRect.top - parentInnerTop) / zoom);
961
1070
  if (topDistance > 0) {
962
1071
  const midX = elementRect.left + elementRect.width / 2;
963
1072
  measurements.push({
@@ -970,7 +1079,7 @@ function calculateParentMeasurements(element, container) {
970
1079
  labelPosition: { x: midX, y: (parentInnerTop + elementRect.top) / 2 }
971
1080
  });
972
1081
  }
973
- const bottomDistance = Math.round(parentInnerBottom - elementRect.bottom);
1082
+ const bottomDistance = Math.round((parentInnerBottom - elementRect.bottom) / zoom);
974
1083
  if (bottomDistance > 0) {
975
1084
  const midX = elementRect.left + elementRect.width / 2;
976
1085
  measurements.push({
@@ -983,7 +1092,7 @@ function calculateParentMeasurements(element, container) {
983
1092
  labelPosition: { x: midX, y: (elementRect.bottom + parentInnerBottom) / 2 }
984
1093
  });
985
1094
  }
986
- const leftDistance = Math.round(elementRect.left - parentInnerLeft);
1095
+ const leftDistance = Math.round((elementRect.left - parentInnerLeft) / zoom);
987
1096
  if (leftDistance > 0) {
988
1097
  const midY = elementRect.top + elementRect.height / 2;
989
1098
  measurements.push({
@@ -996,7 +1105,7 @@ function calculateParentMeasurements(element, container) {
996
1105
  labelPosition: { x: (parentInnerLeft + elementRect.left) / 2, y: midY }
997
1106
  });
998
1107
  }
999
- const rightDistance = Math.round(parentInnerRight - elementRect.right);
1108
+ const rightDistance = Math.round((parentInnerRight - elementRect.right) / zoom);
1000
1109
  if (rightDistance > 0) {
1001
1110
  const midY = elementRect.top + elementRect.height / 2;
1002
1111
  measurements.push({
@@ -1014,6 +1123,7 @@ function calculateParentMeasurements(element, container) {
1014
1123
  function calculateElementMeasurements(from, to) {
1015
1124
  const fromRect = from.getBoundingClientRect();
1016
1125
  const toRect = to.getBoundingClientRect();
1126
+ const zoom = getZoomScale();
1017
1127
  const measurements = [];
1018
1128
  const horizontalOverlap = fromRect.left < toRect.right && fromRect.right > toRect.left;
1019
1129
  const verticalOverlap = fromRect.top < toRect.bottom && fromRect.bottom > toRect.top;
@@ -1022,7 +1132,7 @@ function calculateElementMeasurements(from, to) {
1022
1132
  const overlapBottom = Math.min(fromRect.bottom, toRect.bottom);
1023
1133
  const midY = (overlapTop + overlapBottom) / 2;
1024
1134
  if (fromRect.right <= toRect.left) {
1025
- const distance = Math.round(toRect.left - fromRect.right);
1135
+ const distance = Math.round((toRect.left - fromRect.right) / zoom);
1026
1136
  measurements.push({
1027
1137
  direction: "horizontal",
1028
1138
  x1: fromRect.right,
@@ -1033,7 +1143,7 @@ function calculateElementMeasurements(from, to) {
1033
1143
  labelPosition: { x: (fromRect.right + toRect.left) / 2, y: midY }
1034
1144
  });
1035
1145
  } else if (fromRect.left >= toRect.right) {
1036
- const distance = Math.round(fromRect.left - toRect.right);
1146
+ const distance = Math.round((fromRect.left - toRect.right) / zoom);
1037
1147
  measurements.push({
1038
1148
  direction: "horizontal",
1039
1149
  x1: toRect.right,
@@ -1050,7 +1160,7 @@ function calculateElementMeasurements(from, to) {
1050
1160
  const overlapRight = Math.min(fromRect.right, toRect.right);
1051
1161
  const midX = (overlapLeft + overlapRight) / 2;
1052
1162
  if (fromRect.bottom <= toRect.top) {
1053
- const distance = Math.round(toRect.top - fromRect.bottom);
1163
+ const distance = Math.round((toRect.top - fromRect.bottom) / zoom);
1054
1164
  measurements.push({
1055
1165
  direction: "vertical",
1056
1166
  x1: midX,
@@ -1061,7 +1171,7 @@ function calculateElementMeasurements(from, to) {
1061
1171
  labelPosition: { x: midX, y: (fromRect.bottom + toRect.top) / 2 }
1062
1172
  });
1063
1173
  } else if (fromRect.top >= toRect.bottom) {
1064
- const distance = Math.round(fromRect.top - toRect.bottom);
1174
+ const distance = Math.round((fromRect.top - toRect.bottom) / zoom);
1065
1175
  measurements.push({
1066
1176
  direction: "vertical",
1067
1177
  x1: midX,
@@ -1078,7 +1188,7 @@ function calculateElementMeasurements(from, to) {
1078
1188
  const fromCenterY = fromRect.top + fromRect.height / 2;
1079
1189
  const toCenterX = toRect.left + toRect.width / 2;
1080
1190
  const toCenterY = toRect.top + toRect.height / 2;
1081
- const hDistance = toCenterX > fromCenterX ? Math.round(toRect.left - fromRect.right) : Math.round(fromRect.left - toRect.right);
1191
+ const hDistance = toCenterX > fromCenterX ? Math.round((toRect.left - fromRect.right) / zoom) : Math.round((fromRect.left - toRect.right) / zoom);
1082
1192
  if (hDistance > 0) {
1083
1193
  const startX = toCenterX > fromCenterX ? fromRect.right : fromRect.left;
1084
1194
  const endX = toCenterX > fromCenterX ? toRect.left : toRect.right;
@@ -1093,7 +1203,7 @@ function calculateElementMeasurements(from, to) {
1093
1203
  labelPosition: { x: (startX + endX) / 2, y }
1094
1204
  });
1095
1205
  }
1096
- const vDistance = toCenterY > fromCenterY ? Math.round(toRect.top - fromRect.bottom) : Math.round(fromRect.top - toRect.bottom);
1206
+ const vDistance = toCenterY > fromCenterY ? Math.round((toRect.top - fromRect.bottom) / zoom) : Math.round((fromRect.top - toRect.bottom) / zoom);
1097
1207
  if (vDistance > 0) {
1098
1208
  const x = (fromCenterX + toCenterX) / 2;
1099
1209
  const startY = toCenterY > fromCenterY ? fromRect.bottom : fromRect.top;
@@ -1114,70 +1224,77 @@ function calculateElementMeasurements(from, to) {
1114
1224
  var GUIDELINE_PROXIMITY = 80;
1115
1225
  function calculateGuidelineMeasurements(element, guidelines, mousePosition) {
1116
1226
  if (guidelines.length === 0) return [];
1227
+ const snap = getCanvasSnapshot();
1228
+ const zoom = snap.active ? snap.zoom : 1;
1117
1229
  const rect = element.getBoundingClientRect();
1118
- const scrollX = window.scrollX;
1119
- const scrollY = window.scrollY;
1120
1230
  const measurements = [];
1121
1231
  for (const g of guidelines) {
1232
+ let viewportPos;
1233
+ if (snap.active) {
1234
+ const pan = g.orientation === "horizontal" ? snap.panY : snap.panX;
1235
+ const bo = g.orientation === "horizontal" ? getBodyOffset().y : getBodyOffset().x;
1236
+ viewportPos = bo + (g.position - bo + pan) * zoom;
1237
+ } else {
1238
+ const scroll = g.orientation === "horizontal" ? window.scrollY : window.scrollX;
1239
+ viewportPos = g.position - scroll;
1240
+ }
1122
1241
  if (g.orientation === "horizontal") {
1123
- const gy = g.position - scrollY;
1124
1242
  const midX = rect.left + rect.width / 2;
1125
- if (mousePosition && Math.abs(mousePosition.y - gy) > GUIDELINE_PROXIMITY) continue;
1126
- if (gy < rect.top) {
1127
- const distance = Math.round(rect.top - gy);
1243
+ if (mousePosition && Math.abs(mousePosition.y - viewportPos) > GUIDELINE_PROXIMITY) continue;
1244
+ if (viewportPos < rect.top) {
1245
+ const distance = Math.round((rect.top - viewportPos) / zoom);
1128
1246
  if (distance > 0) {
1129
1247
  measurements.push({
1130
1248
  direction: "vertical",
1131
1249
  x1: midX,
1132
- y1: gy,
1250
+ y1: viewportPos,
1133
1251
  x2: midX,
1134
1252
  y2: rect.top,
1135
1253
  distance,
1136
- labelPosition: { x: midX, y: (gy + rect.top) / 2 }
1254
+ labelPosition: { x: midX, y: (viewportPos + rect.top) / 2 }
1137
1255
  });
1138
1256
  }
1139
- } else if (gy > rect.bottom) {
1140
- const distance = Math.round(gy - rect.bottom);
1257
+ } else if (viewportPos > rect.bottom) {
1258
+ const distance = Math.round((viewportPos - rect.bottom) / zoom);
1141
1259
  if (distance > 0) {
1142
1260
  measurements.push({
1143
1261
  direction: "vertical",
1144
1262
  x1: midX,
1145
1263
  y1: rect.bottom,
1146
1264
  x2: midX,
1147
- y2: gy,
1265
+ y2: viewportPos,
1148
1266
  distance,
1149
- labelPosition: { x: midX, y: (rect.bottom + gy) / 2 }
1267
+ labelPosition: { x: midX, y: (rect.bottom + viewportPos) / 2 }
1150
1268
  });
1151
1269
  }
1152
1270
  }
1153
1271
  } else {
1154
- const gx = g.position - scrollX;
1155
1272
  const midY = rect.top + rect.height / 2;
1156
- if (mousePosition && Math.abs(mousePosition.x - gx) > GUIDELINE_PROXIMITY) continue;
1157
- if (gx < rect.left) {
1158
- const distance = Math.round(rect.left - gx);
1273
+ if (mousePosition && Math.abs(mousePosition.x - viewportPos) > GUIDELINE_PROXIMITY) continue;
1274
+ if (viewportPos < rect.left) {
1275
+ const distance = Math.round((rect.left - viewportPos) / zoom);
1159
1276
  if (distance > 0) {
1160
1277
  measurements.push({
1161
1278
  direction: "horizontal",
1162
- x1: gx,
1279
+ x1: viewportPos,
1163
1280
  y1: midY,
1164
1281
  x2: rect.left,
1165
1282
  y2: midY,
1166
1283
  distance,
1167
- labelPosition: { x: (gx + rect.left) / 2, y: midY }
1284
+ labelPosition: { x: (viewportPos + rect.left) / 2, y: midY }
1168
1285
  });
1169
1286
  }
1170
- } else if (gx > rect.right) {
1171
- const distance = Math.round(gx - rect.right);
1287
+ } else if (viewportPos > rect.right) {
1288
+ const distance = Math.round((viewportPos - rect.right) / zoom);
1172
1289
  if (distance > 0) {
1173
1290
  measurements.push({
1174
1291
  direction: "horizontal",
1175
1292
  x1: rect.right,
1176
1293
  y1: midY,
1177
- x2: gx,
1294
+ x2: viewportPos,
1178
1295
  y2: midY,
1179
1296
  distance,
1180
- labelPosition: { x: (rect.right + gx) / 2, y: midY }
1297
+ labelPosition: { x: (rect.right + viewportPos) / 2, y: midY }
1181
1298
  });
1182
1299
  }
1183
1300
  }
@@ -2555,7 +2672,7 @@ function inferLayoutPrescription(edit, operation, reasons) {
2555
2672
  anchorLabel: formatAnchorRef(anchor)
2556
2673
  };
2557
2674
  });
2558
- const subjectSnapshot = childSnapshots.find((snapshot) => snapshot.child === edit.element);
2675
+ const subjectSnapshot = childSnapshots.find((snapshot2) => snapshot2.child === edit.element);
2559
2676
  const subjectRect = edit.element.getBoundingClientRect();
2560
2677
  const subjectCenterX = subjectRect.left + subjectRect.width / 2;
2561
2678
  const subjectCenterY = subjectRect.top + subjectRect.height / 2;
@@ -2958,6 +3075,7 @@ ${buildMoveExportLines(moveIntent).join("\n")}`;
2958
3075
  getFlexDirection,
2959
3076
  getMoveIntentForEdit,
2960
3077
  getOriginalInlineStyles,
3078
+ getSelectionColors,
2961
3079
  getSizingValue,
2962
3080
  isFlexContainer,
2963
3081
  isInFlowChild,