From 168b9447c97c88ba5ce0e2a03211e4dfc84c9572 Mon Sep 17 00:00:00 2001 From: Sergei Fomin Date: Sat, 14 Jan 2023 20:38:51 +0200 Subject: [PATCH] improves new react demo example (#2162) * improves new react demo example --- demo/react-hooks-controlled-multiple.html | 107 +++++++++++----------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/demo/react-hooks-controlled-multiple.html b/demo/react-hooks-controlled-multiple.html index 5d92cedfd..bb96e828a 100644 --- a/demo/react-hooks-controlled-multiple.html +++ b/demo/react-hooks-controlled-multiple.html @@ -33,9 +33,10 @@

Controlled stack

// // Controlled example // - const ControlledStack = ({ items, addItem, removeItem, id }) => { + const ControlledStack = ({ items, addItem, removeItem, changeItems }) => { const refs = useRef({}) const gridRef = useRef() + const gridContainerRef = useRef(null) refs.current = {} if (Object.keys(refs.current).length !== items.length) { @@ -49,13 +50,13 @@

Controlled stack

// no need to init twice (would will return same grid) or register dup events const grid = gridRef.current = GridStack.init( { - float: true, + float: false, acceptWidgets: true, disableOneColumnMode: true, // side-by-side and fever columns to fit smaller screens column: 6, minRow: 1, }, - `.controlled-${id}` + gridContainerRef.current ) .on('added', (ev, gsItems) => { if (grid._ignoreCB) return; @@ -68,45 +69,35 @@

Controlled stack

}); }) .on('removed', (ev, gsItems) => { + /* Looks like a bug in GridStack */ + const dirtyNodes = grid.engine.getDirtyNodes(); + if (dirtyNodes !== undefined && dirtyNodes.length !== 0) { + const newItems = grid.save(false); + changeItems(newItems); + } + if (grid._ignoreCB) return; gsItems.forEach(n => removeItem(n.id)); }) - + .on('change', (ev, gsItems) => { + const newItems = grid.save(false); + changeItems(newItems); + }) } else { // // update existing grid layout, which is optimized to updates only diffs (will add new/delete items for examples) // const grid = gridRef.current; - const layout = []; - items.forEach((a) => layout.push( + const layout = items.map((a) => refs.current[a.id].current.gridstackNode || {...a, el: refs.current[a.id].current} - )); + ); grid._ignoreCB = true; // hack: ignore added/removed since we're the one doing the update grid.load(layout); delete grid._ignoreCB; } - // NOTE: old code is incorrect as it re-does the GS binding, but dragged item is left behind so you get dup DOM elements with same ids - // grid.batchUpdate() - // items.forEach((a) => { - // // remove existing widgets - // if (refs.current[a.id] && refs.current[a.id].current) { - // grid.removeWidget(refs.current[a.id].current, false, false) - // } - // grid.makeWidget(refs.current[a.id].current) - // }) - // grid.batchUpdate(false) - }, [items]) - useEffect(() => { - return () => { - // console.log('cleanup', id) - // gridRef.current.destroy(false, false) - // gridRef.current = null - } - }) - return ( // ******************** // NOTE: constructing DOM grid items in template when gridstack is also allowed editing (dragging between grids, or adding/removing from say a toolbar) @@ -119,10 +110,10 @@

Controlled stack

// is not robust as things get added, and pollutes the DOM attr for default/missing entries, vs optimized code in GS. // ********************
-
+
{items.map((item, i) => { return ( -
+
@@ -142,32 +133,42 @@

Controlled stack

const [items2, setItems2] = useState([{ id: 'item-2-1', x: 0, y: 0, w: 1, h: 1 }, { id: 'item-2-2', x: 0, y: 1, w: 1, h: 1 }, { id: 'item-2-3', x: 1, y: 0, w: 1, h: 1 }]) return ( -
-
- { - setItems1(items => [...items, item]) - }} - removeItem={(id) => { - setItems1(items => items.filter(i => i.id !== id)) - }} - /> -
-
- { - setItems2(items => [...items, item]) - }} - removeItem={(id) => { - setItems2(items => items.filter(i => i.id !== id)) - }} - /> +
+
+
+
+ +
+ +
-
+
+
+ { + setItems1(items => [...items, item]) + }} + removeItem={(id) => { + setItems1(items => items.filter(i => i.id !== id)) + }} + changeItems={(items) => setItems1(items)} + /> +
+
+ { + setItems2(items => [...items, item]) + }} + removeItem={(id) => { + setItems2(items => items.filter(i => i.id !== id)) + }} + changeItems={(items) => setItems2(items)} + /> +
+
+
) }