diff --git a/CHANGELOG.md b/CHANGELOG.md
index dbb7c2c..fc7ecab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,21 @@
+1.2.9 / 2025-03-09
+==================
+
+ * Fix dim safe for good
+
+1.2.8 / 2025-03-09
+==================
+
+ * Add debug mode
+
+1.2.7 / 2024-07-21
+==================
+
+ * Use board uid and getElementById
+ * Improve performances
+ * Fix bug if missing linked item
+
1.2.6 / 2024-03-09
==================
diff --git a/package-lock.json b/package-lock.json
index 9bfbfc7..07b2272 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "react-sync-board",
- "version": "1.2.6",
+ "version": "1.2.9",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "react-sync-board",
- "version": "1.2.6",
+ "version": "1.2.9",
"license": "MIT",
"dependencies": {
"@react-hookz/web": "^22.0.0",
diff --git a/package.json b/package.json
index a6cc23f..ebae24e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-sync-board",
- "version": "1.2.6",
+ "version": "1.2.9",
"description": "React-sync-board is a board for react",
"type": "module",
"files": [
diff --git a/src/lib/board/Items/Item.jsx b/src/lib/board/Items/Item.jsx
index 0d8ef1f..e14dadf 100644
--- a/src/lib/board/Items/Item.jsx
+++ b/src/lib/board/Items/Item.jsx
@@ -1,9 +1,11 @@
import React, { memo } from "react";
-import ResizeHandler from "./ResizeHandler";
import { css } from "goober";
import deepEqual from "fast-deep-equal";
+import ResizeHandler from "./ResizeHandler";
+import useMainStore from "../store/main";
+
const itemClass = css`
display: inline-block;
transition: transform 150ms;
@@ -184,6 +186,7 @@ const Item = ({
showResizeHandle = true,
}) => {
const itemWrapperRef = React.useRef(null);
+ const [uid] = useMainStore((state) => [state.config.uid]);
const {
component: Component = () => null,
@@ -244,6 +247,7 @@ const Item = ({
{
+ const [getSelection] = useMainStore((state) => [state.getSelection]);
+ return getSelection;
+};
+
+export default useGetSelectedItems;
diff --git a/src/lib/board/Items/useItemActions.js b/src/lib/board/Items/useItemActions.js
index 2fdf4cd..b52c573 100644
--- a/src/lib/board/Items/useItemActions.js
+++ b/src/lib/board/Items/useItemActions.js
@@ -123,10 +123,8 @@ const useItemActions = () => {
getLinkedItems(getStoreItems(), getItemIds(), itemIds),
posDelta
);
-
- updateItemExtent();
},
- [getItemIds, getStoreItems, moveStoreItems, updateItemExtent]
+ [getItemIds, getStoreItems, moveStoreItems]
);
const putItemsOnTop = React.useCallback(
@@ -144,12 +142,12 @@ const useItemActions = () => {
const stickOnGrid = React.useCallback(
(itemIds, { type: globalType, size: globalSize } = {}) => {
- const { boardWrapper } = getConfiguration();
+ const { uid } = getConfiguration();
batchUpdateItems(
itemIds,
(item) => {
- const elem = getItemElem(boardWrapper, item.id);
+ const elem = getItemElem(uid, item.id);
if (!elem) {
return;
@@ -292,10 +290,9 @@ const useItemActions = () => {
});
insertItems(itemsWithPosition, beforeId);
-
- updateItemExtent();
+ placeItems(itemsToInsert.map(({ id }) => id));
},
- [getCenter, insertItems, updateItemExtent]
+ [getCenter, insertItems, placeItems]
);
const pushItem = React.useCallback(
@@ -351,11 +348,11 @@ const useItemActions = () => {
if (hasClass(target, "passthrough")) {
// Get current value
const itemList = getItemIds();
- const { boardWrapper } = getConfiguration();
+ const { uid } = getConfiguration();
// Found element under the cursor
const elements = itemList.reduce((prev, itemId) => {
- const elem = getItemElem(boardWrapper, itemId);
+ const elem = getItemElem(uid, itemId);
const itemRect = elem.getBoundingClientRect();
if (isPointInsideRect({ x: clientX, y: clientY }, itemRect)) {
prev.unshift(elem);
diff --git a/src/lib/board/Selection.jsx b/src/lib/board/Selection.jsx
index ecdd7a1..8d6e914 100644
--- a/src/lib/board/Selection.jsx
+++ b/src/lib/board/Selection.jsx
@@ -45,14 +45,14 @@ const BoundingBox = () => {
// Update selection bounding box
const updateBox = React.useCallback(() => {
const currentSelectedItems = getSelection();
- const { boardWrapperRect, boardWrapper } = getConfiguration();
+ const { boardWrapperRect, uid } = getConfiguration();
if (currentSelectedItems.length === 0) {
setSelectionBox(null);
return;
}
- const boundingBox = getItemsBoundingBox(currentSelectedItems, boardWrapper);
+ const boundingBox = getItemsBoundingBox(currentSelectedItems, uid);
if (!boundingBox) {
setSelectionBox(null);
diff --git a/src/lib/board/useDim.js b/src/lib/board/useDim.js
index b134ecb..100d40d 100644
--- a/src/lib/board/useDim.js
+++ b/src/lib/board/useDim.js
@@ -15,6 +15,8 @@ const TOLERANCE = 100;
const MIN_SIZE = 1000;
const SCALE_TOLERANCE = 0.8;
+let debug = false;
+
/**
* Return new board positions fixed to fit inside the board and not too far from the
* item extent.
@@ -185,6 +187,8 @@ const useDim = () => {
...fn(prev),
};
+ if (debug) console.log("New expected values: ", translateX, translateY, scale, newRotate);
+
const newScale = clampScale(scale);
let [newX, newY] = [translateX, translateY];
@@ -201,11 +205,13 @@ const useDim = () => {
});
}
+ if (debug) console.log("New fixed values: ", newX, newY, newScale, newRotate);
+
updateBoardState({
- translateX: newX,
- translateY: newY,
- scale: newScale,
- rotate: newRotate,
+ translateX: isNaN(newX)? 0: newX,
+ translateY: isNaN(newY)? 0: newY,
+ scale: isNaN(newScale)? clampScale(1): newScale,
+ rotate: isNaN(newRotate) ? 0 : newRotate,
});
},
[clampScale, getBoardState, getConfiguration, updateBoardState]
@@ -280,15 +286,18 @@ const useDim = () => {
const { rotate } = getBoardState();
const { boardWrapperRect, boardSize } = getConfiguration();
- const scaleX = boardWrapperRect.width / (radius * 2);
- const scaleY = boardWrapperRect.height / (radius * 2);
+ const [safeX, safeY, safeRadius] = [x || 0, y||0, radius || 2000]
+
+ const scaleX = boardWrapperRect.width / (safeRadius * 2);
+ const scaleY = boardWrapperRect.height / (safeRadius * 2);
// The scale that fits in all dimensions with a border around
const scale = clampScale(Math.min(scaleX, scaleY) * SCALE_TOLERANCE);
+
// We apply the board transformations
const [translateX, translateY] = transformTo(
- [-boardSize / 2 - x, -boardSize / 2 - y],
+ [-boardSize / 2 - safeX, -boardSize / 2 - safeY],
{
translateX: boardWrapperRect.width / 2,
translateY: boardWrapperRect.height / 2,
@@ -323,11 +332,11 @@ const useDim = () => {
const updateItemExtent = React.useCallback(() => {
// Update item extent
const items = getItemList();
- const { boardWrapper, boardSize } = getConfiguration();
+ const { boardSize, uid } = getConfiguration();
const newRes = items.reduce(
(boundingBox, item) => {
- const elem = getItemElem(boardWrapper, item.id);
+ const elem = getItemElem(uid, item.id);
if (elem) {
boundingBox.left = Math.min(item.x, boundingBox.left);
@@ -392,6 +401,15 @@ const useDim = () => {
200
);
+ React.useEffect(() => {
+ window.debugUpdateExtent = () => updateItemExtent();
+ window.debugDisplayExtent = () =>
+ console.log(getConfiguration().itemExtent);
+ window.debugSetDebug = () => {
+ debug = true;
+ }
+ }, [getConfiguration, updateItemExtent]);
+
return {
setDim: setDimSafe,
rotateBoard,
diff --git a/src/lib/index.js b/src/lib/index.js
index 38d022c..d40c4f6 100644
--- a/src/lib/index.js
+++ b/src/lib/index.js
@@ -3,6 +3,7 @@ export { default as useWire } from "@/hooks/useWire";
export { default as useItems } from "@/board/Items/useItems";
export { default as useDebouncedItems } from "@/board/Items/useDebouncedItems";
export { default as useSelectedItems } from "@/board/Items/useSelectedItems";
+export { default as useGetSelectedItems } from "@/board/Items/useGetSelectedItems";
export { default as useItemActions } from "@/board/Items/useItemActions";
export { default as useItemInteraction } from "@/board/Items/useItemInteraction";
export { default as useAvailableActions } from "@/board/Items/useAvailableActions";
diff --git a/src/lib/utils.js b/src/lib/utils.js
index d59fcde..1dc7215 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -122,18 +122,17 @@ export const isItemInsideElement = (itemElement, otherElem) => {
return result;
};
-export const getItemElem = (wrapper, itemId) => {
+export const getItemElem = (uid, itemId) => {
try {
- const elems = wrapper.getElementsByClassName(`item ${itemId}`);
- const elem = elems[0];
+ const elem = document.getElementById(`${uid}__${itemId}`);
if (!elem) {
console.error(`Missing item ${itemId}`);
}
return elem;
} catch (e) {
console.error(
- `Error while getting item with id ${itemId} with wrapper`,
- wrapper
+ `Error while getting item with id ${itemId} inside wrapper`,
+ uid
);
return undefined;
}
@@ -153,9 +152,9 @@ export const getIdFromElem = (elem) => {
return value;
};
-export const getItemsBoundingBox = (itemIds, wrapper = document) => {
+export const getItemsBoundingBox = (itemIds, uid) => {
const result = itemIds.reduce((prev, itemId) => {
- const elem = getItemElem(wrapper, itemId);
+ const elem = getItemElem(uid, itemId);
if (!elem) {
if (!prev) {
@@ -212,14 +211,19 @@ const getLinkedItemsRecursive = (itemMap, itemIds, alreadyMet = null) => {
return [];
} else {
alreadyMet.add(itemId);
- return [
- itemId,
- ...getLinkedItemsRecursive(
- itemMap,
- itemMap[itemId].linkedItems,
- alreadyMet
- ),
- ];
+ if (itemMap[itemId]) {
+ // If the item has been removed but not from linked list
+ return [
+ itemId,
+ ...getLinkedItemsRecursive(
+ itemMap,
+ itemMap[itemId].linkedItems,
+ alreadyMet
+ ),
+ ];
+ } else {
+ return [];
+ }
}
})
.flat();