@ulgaal/react-grid-layout 1.0.0
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/LICENSE +22 -0
- package/README.md +52 -0
- package/dist/GridItem.js +94 -0
- package/dist/GridItem.js.map +1 -0
- package/dist/PlaceHolder.js +19 -0
- package/dist/PlaceHolder.js.map +1 -0
- package/dist/ReactGridLayout.js +212 -0
- package/dist/ReactGridLayout.js.map +1 -0
- package/dist/ReactGridLayoutReducer.js +163 -0
- package/dist/ReactGridLayoutReducer.js.map +1 -0
- package/dist/assets/react-grid-layout.css +2 -0
- package/dist/index.d.ts +271 -0
- package/dist/index.js +6 -0
- package/dist/logs.js +21 -0
- package/dist/logs.js.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.js +139 -0
- package/dist/utils.js.map +1 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ulrich Gaal
|
|
4
|
+
Copyright (c) 2016 Samuel Reed
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Fork of the of the [react-grid-layout](https://github.com/react-grid-layout/react-grid-layout) library.
|
|
2
|
+
|
|
3
|
+
This library addresses several issues with regards to the original version
|
|
4
|
+
* The code is rewritten in [typescript](https://www.typescriptlang.org/)
|
|
5
|
+
* The code uses only [functional react components](https://react.dev/learn/your-first-component) and [hooks](https://react.dev/reference/react/hooks)
|
|
6
|
+
* The project is based on a [Vitejs](https://vite.dev/) toolchain
|
|
7
|
+
* The code does not have external dependencies (notably, no dependency on [react-draggable](https://www.npmjs.com/package/react-draggable) and [react-resizable](https://www.npmjs.com/package/react-resizable))
|
|
8
|
+
* The code relies on actual [HTML Drag and Drop events](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API), which enables scenarii where one drags a cell from a grid-layout to another, which was not possible with the original version (Indeed, react-draggable is not based on HTML Drag and Drop events)
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Demo and samples](#demo-and-samples)
|
|
13
|
+
|
|
14
|
+
## Installing
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm install @ulgaal/react-grid-layout
|
|
18
|
+
|
|
19
|
+
# or if you use yarn
|
|
20
|
+
|
|
21
|
+
yarn add @ulgaal/react-grid-layout
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```jsx
|
|
27
|
+
// ES6
|
|
28
|
+
import { GridLayout } from "@ulgaal/react-grid-layout";
|
|
29
|
+
|
|
30
|
+
const MyComponent = () => (
|
|
31
|
+
<div>
|
|
32
|
+
<GridLayout
|
|
33
|
+
id={rowId}
|
|
34
|
+
layout={[{i:0, x:0,y:0,w:1,h:1},{i:1, x:1,y:0,w:2,h:1}]}
|
|
35
|
+
cols={5}
|
|
36
|
+
rowHeight={30}
|
|
37
|
+
width={400}
|
|
38
|
+
>
|
|
39
|
+
<span data-id={0}>Hello</span>
|
|
40
|
+
<span data-id={1}>World</span>
|
|
41
|
+
</GridLayout>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Documentation
|
|
47
|
+
|
|
48
|
+
- [Reference documentation](./markdown/index.md) provides a component-level autogenerated doc
|
|
49
|
+
|
|
50
|
+
# Demo and samples
|
|
51
|
+
|
|
52
|
+
Be sure to check the [kitchen-sink app](https://gitlab.com/coder-tribe-group/react-infra/react-grid-layout/demo) as it contains a sample with two grids, cell resizing, cell transfer between grids, ..., complete with source-code, documentation.
|
package/dist/GridItem.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { LEVELS as e, log as t } from "./logs.js";
|
|
2
|
+
import { GRID_MIME_TYPE as n } from "./types.js";
|
|
3
|
+
import { clamp as r, getCellSize as i, getCellStyle as a, getColWidth_ as o, getRowHeight as s } from "./utils.js";
|
|
4
|
+
import { DragDataStore as c, GridDispatch as l } from "./ReactGridLayoutReducer.js";
|
|
5
|
+
import { useCallback as u, useContext as d, useState as f } from "react";
|
|
6
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
7
|
+
//#region src/GridItem.tsx
|
|
8
|
+
var h = (h) => {
|
|
9
|
+
t("GridItem", e.INFO, h);
|
|
10
|
+
let { gridId: g, item: _, metrics: v, children: y, moved: b, isResizable: x } = h, S = d(l), C = d(c), [w, T] = f(null), E = w || !b, D = a(v, _, w || i(v, _)), { isDraggable: O = !0, isResizable: k = !0 } = _, A = o(v), j = s(v), M = u((r) => {
|
|
11
|
+
t("GridItem", e.DEBUG, "handleDragStart", r);
|
|
12
|
+
let { i, w: a, h: o } = _, s = {
|
|
13
|
+
operation: "move",
|
|
14
|
+
gridId: g,
|
|
15
|
+
id: i,
|
|
16
|
+
size: {
|
|
17
|
+
w: a,
|
|
18
|
+
h: o
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
r.dataTransfer.setData(n, JSON.stringify(s)), C[n] = s, r.stopPropagation();
|
|
22
|
+
}, [
|
|
23
|
+
g,
|
|
24
|
+
_,
|
|
25
|
+
C
|
|
26
|
+
]), N = u((n) => {
|
|
27
|
+
t("GridItem", e.DEBUG, "handleDrag", n);
|
|
28
|
+
}, []), P = u((r) => {
|
|
29
|
+
t("GridItem", e.DEBUG, "handleDragEnd", r), delete C[n], S && setTimeout(() => {
|
|
30
|
+
S({
|
|
31
|
+
type: "DRAG_END",
|
|
32
|
+
id: _.i,
|
|
33
|
+
event: r
|
|
34
|
+
});
|
|
35
|
+
}, 0);
|
|
36
|
+
}, [
|
|
37
|
+
S,
|
|
38
|
+
_,
|
|
39
|
+
C
|
|
40
|
+
]), F = u((n) => {
|
|
41
|
+
t("GridItem", e.DEBUG, "handleMouseDown", n), n.preventDefault(), n.stopPropagation();
|
|
42
|
+
let { paddingX: a, paddingY: o, cols: s, div: c } = v;
|
|
43
|
+
if (c) {
|
|
44
|
+
let { minW: l = 1, minH: u = 1, maxH: d = Infinity } = _, { width: f } = c.getBoundingClientRect(), { w: p, h: m } = i(v, {
|
|
45
|
+
w: l,
|
|
46
|
+
h: u
|
|
47
|
+
}), { w: h, h: g } = i(v, _), { clientX: y, clientY: b } = n, x = {};
|
|
48
|
+
x.handleMouseMove = (n) => {
|
|
49
|
+
t("GridItem", e.DEBUG, "handleMouseMove", n);
|
|
50
|
+
let { clientX: i, clientY: c } = n, v = {
|
|
51
|
+
w: Math.max(h + (Math.min(f, i) - y), p),
|
|
52
|
+
h: Math.max(g + (c - b), m)
|
|
53
|
+
};
|
|
54
|
+
T(v);
|
|
55
|
+
let x = Math.ceil((v.w + a - 1) / A), C = Math.ceil((v.h + o) / j);
|
|
56
|
+
S && S({
|
|
57
|
+
type: "RESIZE",
|
|
58
|
+
id: _.i,
|
|
59
|
+
size: {
|
|
60
|
+
w: r(x, l, s - _.x),
|
|
61
|
+
h: r(C, u, d)
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}, x.handleMouseUp = (n) => {
|
|
65
|
+
t("GridItem", e.DEBUG, "handleMouseUp", n), T(null), S && S({ type: "RESIZE_END" }), window.removeEventListener("mousemove", x.handleMouseMove, !0), window.removeEventListener("mouseup", x.handleMouseUp, !0);
|
|
66
|
+
}, window.addEventListener("mousemove", x.handleMouseMove, !0), window.addEventListener("mouseup", x.handleMouseUp, !0);
|
|
67
|
+
}
|
|
68
|
+
}, [
|
|
69
|
+
S,
|
|
70
|
+
_,
|
|
71
|
+
A,
|
|
72
|
+
j,
|
|
73
|
+
v
|
|
74
|
+
]);
|
|
75
|
+
return /* @__PURE__ */ m("div", {
|
|
76
|
+
className: "react-grid-item",
|
|
77
|
+
style: D,
|
|
78
|
+
...v.isDraggable && O ? {
|
|
79
|
+
draggable: !0,
|
|
80
|
+
onDragStart: M,
|
|
81
|
+
onDrag: N,
|
|
82
|
+
onDragEnd: P
|
|
83
|
+
} : {},
|
|
84
|
+
children: [E ? y : null, k && x && E ? /* @__PURE__ */ p("span", {
|
|
85
|
+
className: "react-resizable-handle react-resizable-handle-se",
|
|
86
|
+
onMouseDown: F
|
|
87
|
+
}) : null]
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
h.displayName = "GridItem";
|
|
91
|
+
//#endregion
|
|
92
|
+
export { h as GridItem };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=GridItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GridItem.js","names":[],"sources":["../src/GridItem.tsx"],"sourcesContent":["import { useCallback, useContext, useState, type DragEventHandler, type FunctionComponent, type ReactNode } from 'react'\nimport './GridItem.css'\nimport { LEVELS, log } from './logs'\nimport { DragDataStore, GridDispatch } from './ReactGridLayoutReducer'\nimport { GRID_MIME_TYPE, type DimensionsType, type GridMetrics, type GridMoveOperation, type LayoutItemType } from './types'\nimport { clamp, getCellSize, getCellStyle, getColWidth_, getRowHeight } from './utils'\n\ninterface GridItemProps {\n gridId: string,\n item: LayoutItemType,\n metrics: GridMetrics,\n children: ReactNode,\n moved: boolean,\n isResizable: boolean\n}\n\nexport const GridItem: FunctionComponent<GridItemProps> = props => {\n log('GridItem', LEVELS.INFO, props)\n const { gridId, item, metrics, children, moved, isResizable: gridIsResizable } = props\n const dispatch = useContext(GridDispatch)\n const dragDataStore = useContext(DragDataStore)\n\n const [pixelSize, setPixelSize] = useState<DimensionsType | null>(null)\n const visible = pixelSize || !moved\n const size = pixelSize || getCellSize(metrics, item)\n const style = getCellStyle(metrics, item, size)\n const { isDraggable = true, isResizable = true } = item\n const colWidth = getColWidth_(metrics)\n const rowHeight = getRowHeight(metrics)\n\n const handleDragStart = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridItem', LEVELS.DEBUG, 'handleDragStart', event)\n const { i, w, h } = item\n const op: GridMoveOperation = {\n operation: 'move',\n gridId,\n id: i,\n size: {\n w, h\n }\n }\n event.dataTransfer.setData(\n GRID_MIME_TYPE,\n JSON.stringify(op)\n )\n // eslint-disable-next-line react-hooks/immutability\n dragDataStore[GRID_MIME_TYPE] = op\n event.stopPropagation()\n },\n [gridId, item, dragDataStore]\n )\n const handleDrag = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridItem', LEVELS.DEBUG, 'handleDrag', event)\n },\n []\n )\n const handleDragEnd = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridItem', LEVELS.DEBUG, 'handleDragEnd', event)\n // eslint-disable-next-line react-hooks/immutability\n delete dragDataStore[GRID_MIME_TYPE]\n if (dispatch) {\n setTimeout(() => {\n dispatch({\n type: 'DRAG_END',\n id: item.i,\n event\n })\n }, 0)\n }\n },\n [dispatch, item, dragDataStore]\n )\n\n const handleMouseDown = useCallback<DragEventHandler<HTMLSpanElement>>(\n event => {\n log('GridItem', LEVELS.DEBUG, 'handleMouseDown', event)\n event.preventDefault()\n event.stopPropagation()\n const { paddingX, paddingY, cols, div } = metrics\n if (div) {\n const {\n minW = 1,\n minH = 1,\n maxH = Number.POSITIVE_INFINITY\n } = item\n const { width } = div.getBoundingClientRect()\n const { w: minWidth, h: minHeight } = getCellSize(metrics, { w: minW, h: minH })\n const { w: w0, h: h0 } = getCellSize(metrics, item)\n const { clientX: x0, clientY: y0 } = event\n const handlers = {} as {\n handleMouseMove: (event: MouseEvent) => void,\n handleMouseUp: (event: MouseEvent) => void\n }\n handlers.handleMouseMove = event => {\n log('GridItem', LEVELS.DEBUG, 'handleMouseMove', event)\n const { clientX: x1, clientY: y1 } = event\n const itemSize: DimensionsType = {\n w: Math.max(w0 + (Math.min(width, x1) - x0), minWidth),\n h: Math.max(h0 + (y1 - y0), minHeight)\n }\n setPixelSize(itemSize)\n const w = Math.ceil((itemSize.w + paddingX - 1) / colWidth)\n const h = Math.ceil((itemSize.h + paddingY) / rowHeight)\n if (dispatch) {\n dispatch({\n type: 'RESIZE',\n id: item.i,\n size: {\n w: clamp(w, minW, cols - item.x),\n h: clamp(h, minH, maxH)\n }\n })\n }\n }\n handlers.handleMouseUp = event => {\n log('GridItem', LEVELS.DEBUG, 'handleMouseUp', event)\n setPixelSize(null)\n if (dispatch) {\n dispatch({\n type: 'RESIZE_END',\n })\n }\n window.removeEventListener<'mousemove'>('mousemove', handlers.handleMouseMove, true)\n window.removeEventListener<'mouseup'>('mouseup', handlers.handleMouseUp, true)\n }\n window.addEventListener<'mousemove'>('mousemove', handlers.handleMouseMove, true)\n window.addEventListener<'mouseup'>('mouseup', handlers.handleMouseUp, true)\n }\n },\n [dispatch, item, colWidth, rowHeight, metrics]\n )\n\n return (\n <div\n className='react-grid-item'\n style={style}\n {\n ...(metrics.isDraggable && isDraggable)\n ? {\n draggable: true,\n onDragStart: handleDragStart,\n onDrag: handleDrag,\n onDragEnd: handleDragEnd,\n }\n : {}\n }\n >\n {visible ? children : null}\n {\n isResizable && gridIsResizable && visible\n ? <span\n className='react-resizable-handle react-resizable-handle-se'\n onMouseDown={handleMouseDown}\n />\n : null\n }\n </div>\n )\n}\n\nGridItem.displayName = 'GridItem'\n"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { LEVELS as e, log as t } from "./logs.js";
|
|
2
|
+
import "./types.js";
|
|
3
|
+
import { getCellSize as n, getCellStyle as r } from "./utils.js";
|
|
4
|
+
import "react";
|
|
5
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
6
|
+
//#region src/PlaceHolder.tsx
|
|
7
|
+
var a = (a) => {
|
|
8
|
+
t("PlaceHolder", e.INFO, a);
|
|
9
|
+
let { item: o, metrics: s } = a;
|
|
10
|
+
return /* @__PURE__ */ i("div", {
|
|
11
|
+
style: r(s, o, n(s, o)),
|
|
12
|
+
children: /* @__PURE__ */ i("div", { className: "react-grid-placeholder react-grid-item" })
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
a.displayName = "PlaceHolder";
|
|
16
|
+
//#endregion
|
|
17
|
+
export { a as PlaceHolder };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=PlaceHolder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaceHolder.js","names":[],"sources":["../src/PlaceHolder.tsx"],"sourcesContent":["import { type FunctionComponent } from 'react'\nimport { LEVELS, log } from './logs'\nimport './PlaceHolder.css'\nimport { type GridMetrics, type LayoutItemType } from './types'\nimport { getCellSize, getCellStyle } from './utils'\n\ninterface PlaceHolderProps {\n item: LayoutItemType,\n metrics: GridMetrics,\n}\n\nexport const PlaceHolder: FunctionComponent<PlaceHolderProps> = props => {\n log('PlaceHolder', LEVELS.INFO, props)\n const { item, metrics } = props\n const style = getCellStyle(metrics, item, getCellSize(metrics, item))\n\n return (\n <div style={style}>\n <div className='react-grid-placeholder react-grid-item' />\n </div>\n )\n}\n\nPlaceHolder.displayName = 'PlaceHolder'\n"],"mappings":";;;;;;AAWA,IAAa,KAAmD,MAAS;CACvE,EAAI,eAAe,EAAO,MAAM,CAAK;CACrC,IAAM,EAAE,SAAM,eAAY;CAG1B,OACE,kBAAC,OAAD;EAAY,OAHA,EAAa,GAAS,GAAM,EAAY,GAAS,CAAI,CAGrD;YACV,kBAAC,OAAD,EAAK,WAAU,yCAA0C,CAAA;CACtD,CAAA;AAET;AAEA,EAAY,cAAc"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { LEVELS as e, log as t } from "./logs.js";
|
|
2
|
+
import { GRID_MIME_TYPE as n, NEW_ITEM_ID as r } from "./types.js";
|
|
3
|
+
import { containerHeight as i } from "./utils.js";
|
|
4
|
+
import { DragDataStore as a, GridDispatch as o, gridLayoutReducer as s } from "./ReactGridLayoutReducer.js";
|
|
5
|
+
import { GridItem as c } from "./GridItem.js";
|
|
6
|
+
import { PlaceHolder as l } from "./PlaceHolder.js";
|
|
7
|
+
import { useCallback as u, useContext as d, useEffect as f, useMemo as p, useReducer as m, useRef as h } from "react";
|
|
8
|
+
import { jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
9
|
+
//#region src/ReactGridLayout.tsx
|
|
10
|
+
var v = ({ id: v, width: y, cols: b = 12, rowHeight: x = 150, minHeight: S = 0, layout: C, children: w, paddingX: T = 10, paddingY: E = 10, marginX: D = 10, marginY: O = 10, style: k, className: A, isDraggable: j = !0, isResizable: M = !0, onLayoutChange: N, onAdd: P, onRemove: F, onDragOver: I }) => {
|
|
11
|
+
let L = {
|
|
12
|
+
id: v,
|
|
13
|
+
width: y,
|
|
14
|
+
cols: b,
|
|
15
|
+
rowHeight: x,
|
|
16
|
+
minHeight: S,
|
|
17
|
+
layout: C,
|
|
18
|
+
children: w,
|
|
19
|
+
paddingX: T,
|
|
20
|
+
paddingY: E,
|
|
21
|
+
marginX: D,
|
|
22
|
+
marginY: O,
|
|
23
|
+
style: k,
|
|
24
|
+
className: A,
|
|
25
|
+
isDraggable: j,
|
|
26
|
+
isResizable: M,
|
|
27
|
+
onLayoutChange: N,
|
|
28
|
+
onAdd: P,
|
|
29
|
+
onRemove: F,
|
|
30
|
+
onDragOver: I
|
|
31
|
+
}, R = h(null), [z, B] = m(s, {
|
|
32
|
+
id: v,
|
|
33
|
+
idToChild: {},
|
|
34
|
+
current: { idToLayoutItem: {} },
|
|
35
|
+
next: { idToLayoutItem: {} },
|
|
36
|
+
extent: {
|
|
37
|
+
xMax: 0,
|
|
38
|
+
yMax: 0
|
|
39
|
+
},
|
|
40
|
+
metrics: {
|
|
41
|
+
id: v,
|
|
42
|
+
width: y,
|
|
43
|
+
cols: b,
|
|
44
|
+
rowHeight: x,
|
|
45
|
+
paddingX: T,
|
|
46
|
+
paddingY: E,
|
|
47
|
+
marginX: D,
|
|
48
|
+
marginY: O,
|
|
49
|
+
isDraggable: j,
|
|
50
|
+
isResizable: M,
|
|
51
|
+
div: null
|
|
52
|
+
},
|
|
53
|
+
movedId: null,
|
|
54
|
+
dragIsOutside: !1,
|
|
55
|
+
onLayoutChange: N,
|
|
56
|
+
onRemove: F,
|
|
57
|
+
p0: null
|
|
58
|
+
});
|
|
59
|
+
t("GridLayout", e.INFO, L, z);
|
|
60
|
+
let { current: V, next: H, movedId: U, extent: W, metrics: G, dragIsOutside: K, idToChild: q, p0: J } = z, { idToLayoutItem: Y } = U === null ? V : H, X = d(a), Z = p(() => {
|
|
61
|
+
let { yMax: e } = W;
|
|
62
|
+
return {
|
|
63
|
+
...k,
|
|
64
|
+
height: `${i({
|
|
65
|
+
paddingY: E,
|
|
66
|
+
marginY: O,
|
|
67
|
+
rowHeight: x,
|
|
68
|
+
yMax: e,
|
|
69
|
+
minHeight: S
|
|
70
|
+
})}px`
|
|
71
|
+
};
|
|
72
|
+
}, [
|
|
73
|
+
E,
|
|
74
|
+
O,
|
|
75
|
+
k,
|
|
76
|
+
x,
|
|
77
|
+
S,
|
|
78
|
+
W
|
|
79
|
+
]), Q = u((r) => {
|
|
80
|
+
t("GridLayout", e.DEBUG, "handleDragOver", r, X);
|
|
81
|
+
let i = X[n];
|
|
82
|
+
if (i) i.gridId === v ? J && (B({
|
|
83
|
+
type: "MOVE_CELL",
|
|
84
|
+
delta: {
|
|
85
|
+
x: r.clientX - J.x,
|
|
86
|
+
y: r.clientY - J.y
|
|
87
|
+
},
|
|
88
|
+
id: i.id
|
|
89
|
+
}), r.preventDefault()) : (B({
|
|
90
|
+
type: "ADD_CELL",
|
|
91
|
+
coordinates: {
|
|
92
|
+
x: r.clientX,
|
|
93
|
+
y: r.clientY
|
|
94
|
+
},
|
|
95
|
+
size: i.size
|
|
96
|
+
}), r.preventDefault());
|
|
97
|
+
else if (I) {
|
|
98
|
+
let e = I(v, r);
|
|
99
|
+
e && (B({
|
|
100
|
+
type: "ADD_CELL",
|
|
101
|
+
coordinates: {
|
|
102
|
+
x: r.clientX,
|
|
103
|
+
y: r.clientY
|
|
104
|
+
},
|
|
105
|
+
size: e
|
|
106
|
+
}), r.preventDefault(), r.dataTransfer.dropEffect = "copy");
|
|
107
|
+
}
|
|
108
|
+
}, [
|
|
109
|
+
B,
|
|
110
|
+
v,
|
|
111
|
+
I,
|
|
112
|
+
X,
|
|
113
|
+
J
|
|
114
|
+
]), $ = u((i) => {
|
|
115
|
+
t("GridLayout", e.DEBUG, "handleDrop", i, X);
|
|
116
|
+
let a = !1, o = X[n];
|
|
117
|
+
if (o && o.gridId === v && (a = !0, N && setTimeout(() => {
|
|
118
|
+
N(v, Object.values(Y));
|
|
119
|
+
}, 0)), !a) {
|
|
120
|
+
let e = Object.keys(Y).indexOf(r);
|
|
121
|
+
e !== -1 && P && P(v, Object.values(Y), e, i);
|
|
122
|
+
}
|
|
123
|
+
B({
|
|
124
|
+
type: "COMMIT_CHANGE",
|
|
125
|
+
idToLayoutItem: Y
|
|
126
|
+
});
|
|
127
|
+
}, [
|
|
128
|
+
B,
|
|
129
|
+
v,
|
|
130
|
+
Y,
|
|
131
|
+
P,
|
|
132
|
+
N,
|
|
133
|
+
X
|
|
134
|
+
]), ee = u((n) => {
|
|
135
|
+
t("GridLayout", e.DEBUG, "handleDragEnter", n, n.relatedTarget), K && (B({ type: "DRAG_ENTER" }), n.preventDefault());
|
|
136
|
+
}, [B, K]), te = u((n) => {
|
|
137
|
+
t("GridLayout", e.DEBUG, "handleDragLeave", n.relatedTarget);
|
|
138
|
+
let r = n.relatedTarget, { current: i } = R;
|
|
139
|
+
r !== null && i !== null && !i.contains(r) && B({ type: "DRAG_LEAVE" });
|
|
140
|
+
}, [B]), ne = u((n) => {
|
|
141
|
+
t("GridLayout", e.DEBUG, "handleMouseDown", n), B({
|
|
142
|
+
type: "SET_PO",
|
|
143
|
+
p0: {
|
|
144
|
+
x: n.clientX,
|
|
145
|
+
y: n.clientY
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}, [B]);
|
|
149
|
+
return f(() => {
|
|
150
|
+
t("GridLayout", e.DEBUG, "SYNC");
|
|
151
|
+
let { current: n } = R;
|
|
152
|
+
B({
|
|
153
|
+
type: "SYNC",
|
|
154
|
+
id: v,
|
|
155
|
+
layout: C,
|
|
156
|
+
children: w,
|
|
157
|
+
metrics: {
|
|
158
|
+
id: v,
|
|
159
|
+
width: y,
|
|
160
|
+
cols: b,
|
|
161
|
+
rowHeight: x,
|
|
162
|
+
paddingX: T,
|
|
163
|
+
paddingY: E,
|
|
164
|
+
marginX: D,
|
|
165
|
+
marginY: O,
|
|
166
|
+
isDraggable: j,
|
|
167
|
+
isResizable: M,
|
|
168
|
+
div: n
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}, [
|
|
172
|
+
C,
|
|
173
|
+
w,
|
|
174
|
+
y,
|
|
175
|
+
b,
|
|
176
|
+
x,
|
|
177
|
+
T,
|
|
178
|
+
D,
|
|
179
|
+
O,
|
|
180
|
+
j,
|
|
181
|
+
M,
|
|
182
|
+
v,
|
|
183
|
+
E
|
|
184
|
+
]), /* @__PURE__ */ g("div", {
|
|
185
|
+
style: Z,
|
|
186
|
+
className: `react-grid-layout${A ? ` ${A}` : ""}`,
|
|
187
|
+
ref: R,
|
|
188
|
+
onDragOver: Q,
|
|
189
|
+
onDrop: $,
|
|
190
|
+
onDragEnter: ee,
|
|
191
|
+
onDragLeave: te,
|
|
192
|
+
onMouseDown: ne,
|
|
193
|
+
children: /* @__PURE__ */ _(o.Provider, {
|
|
194
|
+
value: B,
|
|
195
|
+
children: [U && !K ? /* @__PURE__ */ g(l, {
|
|
196
|
+
item: Y[U],
|
|
197
|
+
metrics: G
|
|
198
|
+
}) : null, Object.entries(q).map(([e, t]) => /* @__PURE__ */ g(c, {
|
|
199
|
+
gridId: v,
|
|
200
|
+
item: Y[e] || V.idToLayoutItem[U || ""],
|
|
201
|
+
metrics: G,
|
|
202
|
+
moved: U === e,
|
|
203
|
+
isResizable: M,
|
|
204
|
+
children: t
|
|
205
|
+
}, e))]
|
|
206
|
+
})
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
//#endregion
|
|
210
|
+
export { v as GridLayout };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=ReactGridLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactGridLayout.js","names":[],"sources":["../src/ReactGridLayout.tsx"],"sourcesContent":["import { useCallback, useContext, useEffect, useMemo, useReducer, useRef, type CSSProperties, type DragEventHandler, type FunctionComponent, type MouseEventHandler } from 'react'\nimport { GridItem } from './GridItem'\nimport { LEVELS, log } from './logs'\nimport { PlaceHolder } from './PlaceHolder'\nimport { DragDataStore, GridDispatch, gridLayoutReducer } from './ReactGridLayoutReducer'\nimport './resizable.css'\nimport './styles.css'\nimport { GRID_MIME_TYPE, NEW_ITEM_ID, type GridLayoutProps, type GridMoveOperation } from './types'\nimport { containerHeight } from './utils'\n\n/**\n * A reactive, fluid grid layout with draggable, resizable components.\n * The grid supports the following operations:\n * Re-arranging its children by dragging them to their new position (triggers onLayoutChange)\n * Resizing its children using their resize handles (triggers onLayoutChange)\n * Remove one of its children, by dragging it outside the grid boundaries (triggers onRemove)\n * Accepting (by implementing onDragOver) new children from drag and drop (triggers onAdd) ;\n * these new children may come from another grid (in this case, onRemove in called on\n * the source grid and onAdd in called on the destination grid)\n */\nexport const GridLayout: FunctionComponent<GridLayoutProps> = ({\n id,\n width,\n cols = 12,\n rowHeight = 150,\n minHeight = 0,\n layout,\n children,\n paddingX = 10,\n paddingY = 10,\n marginX = 10,\n marginY = 10,\n style,\n className,\n isDraggable = true,\n isResizable = true,\n onLayoutChange,\n onAdd,\n onRemove,\n onDragOver,\n }) => {\n const props = {\n id,\n width,\n cols,\n rowHeight,\n minHeight,\n layout,\n children,\n paddingX,\n paddingY,\n marginX,\n marginY,\n style,\n className,\n isDraggable,\n isResizable,\n onLayoutChange,\n onAdd,\n onRemove,\n onDragOver\n }\n const ref = useRef<HTMLDivElement | null>(null)\n const [state, dispatch] = useReducer(gridLayoutReducer, {\n id,\n idToChild: {},\n current: {\n idToLayoutItem: {},\n },\n next: {\n idToLayoutItem: {},\n },\n extent: {\n xMax: 0,\n yMax: 0\n },\n metrics: {\n id,\n width,\n cols,\n rowHeight,\n paddingX,\n paddingY,\n marginX,\n marginY,\n isDraggable,\n isResizable,\n div: null\n },\n movedId: null,\n dragIsOutside: false,\n onLayoutChange,\n onRemove,\n p0: null\n })\n log('GridLayout', LEVELS.INFO, props, state)\n const { current, next, movedId, extent, metrics, dragIsOutside, idToChild, p0 } = state\n const { idToLayoutItem } = movedId !== null ? next : current\n const dragDataStore = useContext(DragDataStore)\n\n const gridStyle = useMemo<CSSProperties>(() => {\n const { yMax } = extent\n return {\n ...style,\n height: `${containerHeight({ paddingY, marginY, rowHeight, yMax, minHeight })}px`,\n }\n }, [paddingY, marginY, style, rowHeight, minHeight, extent])\n\n const handleDragOver = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridLayout', LEVELS.DEBUG, 'handleDragOver', event, dragDataStore)\n const op: GridMoveOperation | undefined = dragDataStore[GRID_MIME_TYPE]\n if (op) {\n if (op.gridId === id) {\n if (p0) {\n // The user wants to change layout\n dispatch({\n type: 'MOVE_CELL',\n delta: {\n x: event.clientX - p0.x,\n y: event.clientY - p0.y\n },\n id: op.id\n })\n event.preventDefault()\n }\n } else {\n // The user wants to transfer an element from another grid\n dispatch({\n type: 'ADD_CELL',\n coordinates: {\n x: event.clientX,\n y: event.clientY\n },\n size: op.size,\n })\n event.preventDefault()\n }\n } else if (onDragOver) {\n // The use wants to add an element from an external drag source\n const size = onDragOver(id, event)\n if (size) {\n dispatch({\n type: 'ADD_CELL',\n coordinates: {\n x: event.clientX,\n y: event.clientY\n },\n size,\n })\n event.preventDefault()\n event.dataTransfer.dropEffect = 'copy'\n }\n }\n },\n [dispatch, id, onDragOver, dragDataStore, p0]\n )\n\n const handleDrop = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridLayout', LEVELS.DEBUG, 'handleDrop', event, dragDataStore)\n let internalMove = false\n const op: GridMoveOperation | undefined = dragDataStore[GRID_MIME_TYPE]\n if (op) {\n if (op.gridId === id) {\n internalMove = true\n if (onLayoutChange) {\n setTimeout(() => {\n onLayoutChange(id, Object.values(idToLayoutItem))\n }, 0)\n }\n }\n }\n if (!internalMove) {\n const index = Object.keys(idToLayoutItem).indexOf(NEW_ITEM_ID)\n if (index !== -1) {\n if (onAdd) {\n onAdd(id, Object.values(idToLayoutItem), index, event)\n }\n }\n }\n dispatch({\n type: 'COMMIT_CHANGE',\n idToLayoutItem\n })\n },\n [dispatch, id, idToLayoutItem, onAdd, onLayoutChange, dragDataStore]\n )\n\n const handleDragEnter = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridLayout', LEVELS.DEBUG, 'handleDragEnter', event, event.relatedTarget)\n if (dragIsOutside) {\n dispatch({\n type: 'DRAG_ENTER'\n })\n event.preventDefault()\n }\n },\n [dispatch, dragIsOutside]\n )\n\n const handleDragLeave = useCallback<DragEventHandler<HTMLDivElement>>(\n event => {\n log('GridLayout', LEVELS.DEBUG, 'handleDragLeave', event.relatedTarget)\n const elt = event.relatedTarget as HTMLElement | null\n const { current } = ref\n if (elt !== null && current !== null && !current.contains(elt)) {\n dispatch({\n type: 'DRAG_LEAVE'\n })\n }\n },\n [dispatch]\n )\n\n const handleMouseDown = useCallback<MouseEventHandler<HTMLDivElement>>(\n event => {\n log('GridLayout', LEVELS.DEBUG, 'handleMouseDown', event)\n dispatch({ type: 'SET_PO', p0: { x: event.clientX, y: event.clientY } })\n },\n [dispatch]\n )\n\n useEffect(() => {\n log('GridLayout', LEVELS.DEBUG, 'SYNC')\n const { current } = ref\n dispatch({\n type: 'SYNC',\n id,\n layout,\n children,\n metrics: {\n id,\n width,\n cols,\n rowHeight,\n paddingX,\n paddingY,\n marginX,\n marginY,\n isDraggable,\n isResizable,\n div: current\n },\n })\n }, [layout, children, width, cols, rowHeight, paddingX, marginX, marginY, isDraggable, isResizable, id, paddingY])\n\n return (\n <div\n style={gridStyle}\n className={`react-grid-layout${className ? ` ${className}` : ''}`}\n ref={ref}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onMouseDown={handleMouseDown}\n >\n <GridDispatch.Provider value={dispatch}>\n {\n (movedId && !dragIsOutside)\n ? (\n <PlaceHolder\n item={idToLayoutItem[movedId]}\n metrics={metrics}\n />\n )\n : null\n }\n {Object.entries(idToChild).map(([itemId, node]) => {\n const item = idToLayoutItem[itemId] || current.idToLayoutItem[movedId || '']\n return (\n <GridItem\n key={itemId}\n gridId={id}\n item={item}\n metrics={metrics}\n moved={movedId === itemId}\n isResizable={isResizable}\n >\n {node}\n </GridItem>\n )\n })}\n </GridDispatch.Provider>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAoBA,IAAa,KAAkD,EAC3D,OACA,UACA,UAAO,IACP,eAAY,KACZ,eAAY,GACZ,WACA,aACA,cAAW,IACX,cAAW,IACX,aAAU,IACV,aAAU,IACV,UACA,cACA,iBAAc,IACd,iBAAc,IACd,mBACA,UACA,aACA,oBACI;CACN,IAAM,IAAQ;EACZ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACM,IAAM,EAA8B,IAAI,GACxC,CAAC,GAAO,KAAY,EAAW,GAAmB;EACtD;EACA,WAAW,CAAC;EACZ,SAAS,EACP,gBAAgB,CAAC,EACnB;EACA,MAAM,EACJ,gBAAgB,CAAC,EACnB;EACA,QAAQ;GACN,MAAM;GACN,MAAM;EACR;EACA,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,KAAK;EACP;EACA,SAAS;EACT,eAAe;EACf;EACA;EACA,IAAI;CACN,CAAC;CACD,EAAI,cAAc,EAAO,MAAM,GAAO,CAAK;CAC3C,IAAM,EAAE,YAAS,SAAM,YAAS,WAAQ,YAAS,kBAAe,cAAW,UAAO,GAC5E,EAAE,sBAAmB,MAAY,OAAc,IAAP,GACxC,IAAgB,EAAW,CAAa,GAExC,IAAY,QAA6B;EAC7C,IAAM,EAAE,YAAS;EACjB,OAAO;GACL,GAAG;GACH,QAAQ,GAAG,EAAgB;IAAE;IAAU;IAAS;IAAW;IAAM;GAAU,CAAC,EAAE;EAChF;CACF,GAAG;EAAC;EAAU;EAAS;EAAO;EAAW;EAAW;CAAM,CAAC,GAErD,IAAiB,GACrB,MAAS;EACP,EAAI,cAAc,EAAO,OAAO,kBAAkB,GAAO,CAAa;EACtE,IAAM,IAAoC,EAAc;EACxD,IAAI,GACF,AAAI,EAAG,WAAW,IACZ,MAEF,EAAS;GACP,MAAM;GACN,OAAO;IACL,GAAG,EAAM,UAAU,EAAG;IACtB,GAAG,EAAM,UAAU,EAAG;GACxB;GACA,IAAI,EAAG;EACT,CAAC,GACD,EAAM,eAAe,MAIvB,EAAS;GACP,MAAM;GACN,aAAa;IACX,GAAG,EAAM;IACT,GAAG,EAAM;GACX;GACA,MAAM,EAAG;EACX,CAAC,GACD,EAAM,eAAe;OAElB,IAAI,GAAY;GAErB,IAAM,IAAO,EAAW,GAAI,CAAK;GACjC,AAAI,MACF,EAAS;IACP,MAAM;IACN,aAAa;KACX,GAAG,EAAM;KACT,GAAG,EAAM;IACX;IACA;GACF,CAAC,GACD,EAAM,eAAe,GACrB,EAAM,aAAa,aAAa;EAEpC;CACF,GACA;EAAC;EAAU;EAAI;EAAY;EAAe;CAAE,CAC9C,GAEM,IAAa,GACjB,MAAS;EACP,EAAI,cAAc,EAAO,OAAO,cAAc,GAAO,CAAa;EAClE,IAAI,IAAe,IACb,IAAoC,EAAc;EAWxD,IAVI,KACE,EAAG,WAAW,MAChB,IAAe,IACX,KACF,iBAAiB;GACf,EAAe,GAAI,OAAO,OAAO,CAAc,CAAC;EAClD,GAAG,CAAC,IAIN,CAAC,GAAc;GACjB,IAAM,IAAQ,OAAO,KAAK,CAAc,EAAE,QAAQ,CAAW;GAC7D,AAAI,MAAU,MACR,KACF,EAAM,GAAI,OAAO,OAAO,CAAc,GAAG,GAAO,CAAK;EAG3D;EACA,EAAS;GACP,MAAM;GACN;EACF,CAAC;CACH,GACA;EAAC;EAAU;EAAI;EAAgB;EAAO;EAAgB;CAAa,CACrE,GAEM,KAAkB,GACtB,MAAS;EAEP,AADA,EAAI,cAAc,EAAO,OAAO,mBAAmB,GAAO,EAAM,aAAa,GACzE,MACF,EAAS,EACP,MAAM,aACR,CAAC,GACD,EAAM,eAAe;CAEzB,GACA,CAAC,GAAU,CAAa,CAC1B,GAEM,KAAkB,GACtB,MAAS;EACP,EAAI,cAAc,EAAO,OAAO,mBAAmB,EAAM,aAAa;EACtE,IAAM,IAAM,EAAM,eACZ,EAAE,eAAY;EACpB,AAAI,MAAQ,QAAQ,MAAY,QAAQ,CAAC,EAAQ,SAAS,CAAG,KAC3D,EAAS,EACP,MAAM,aACR,CAAC;CAEL,GACA,CAAC,CAAQ,CACX,GAEM,KAAkB,GACtB,MAAS;EAEP,AADA,EAAI,cAAc,EAAO,OAAO,mBAAmB,CAAK,GACxD,EAAS;GAAE,MAAM;GAAU,IAAI;IAAE,GAAG,EAAM;IAAS,GAAG,EAAM;GAAQ;EAAE,CAAC;CACzE,GACA,CAAC,CAAQ,CACX;CA0BA,OAxBA,QAAgB;EACd,EAAI,cAAc,EAAO,OAAO,MAAM;EACtC,IAAM,EAAE,eAAY;EACpB,EAAS;GACP,MAAM;GACN;GACA;GACA;GACA,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,KAAK;GACP;EACF,CAAC;CACH,GAAG;EAAC;EAAQ;EAAU;EAAO;EAAM;EAAW;EAAU;EAAS;EAAS;EAAa;EAAa;EAAI;CAAQ,CAAC,GAG/G,kBAAC,OAAD;EACE,OAAO;EACP,WAAW,oBAAoB,IAAY,IAAI,MAAc;EACxD;EACL,YAAY;EACZ,QAAQ;EACR,aAAa;EACb,aAAa;EACb,aAAa;YAEb,kBAAC,EAAa,UAAd;GAAuB,OAAO;aAA9B,CAEK,KAAW,CAAC,IAEX,kBAAC,GAAD;IACE,MAAM,EAAe;IACZ;GACV,CAAA,IAED,MAEH,OAAO,QAAQ,CAAS,EAAE,KAAK,CAAC,GAAQ,OAGrC,kBAAC,GAAD;IAEE,QAAQ;IACF,MALG,EAAe,MAAW,EAAQ,eAAe,KAAW;IAM5D;IACT,OAAO,MAAY;IACN;cAEZ;GACO,GARH,CAQG,CAEb,CACoB;;CACpB,CAAA;AAET"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { LEVELS as e, log as t } from "./logs.js";
|
|
2
|
+
import { NEW_ITEM_ID as n } from "./types.js";
|
|
3
|
+
import { byId as r, clampX as i, compact as a, getExtent as o, moveElement as s, toGridCoordinates as c, toGridCoordinates2 as l } from "./utils.js";
|
|
4
|
+
import { Children as u, createContext as d, isValidElement as f } from "react";
|
|
5
|
+
//#region src/ReactGridLayoutReducer.tsx
|
|
6
|
+
var p = d(null), m = d({}), h = (d, p) => {
|
|
7
|
+
t("gridLayoutReducer", e.INFO, d, p);
|
|
8
|
+
let { type: m } = p;
|
|
9
|
+
switch (m) {
|
|
10
|
+
case "SET_PO": {
|
|
11
|
+
let { p0: e } = p;
|
|
12
|
+
return {
|
|
13
|
+
...d,
|
|
14
|
+
p0: e
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
case "MOVE_CELL": {
|
|
18
|
+
let { delta: e, id: t } = p, { metrics: n, current: c, movedId: u } = d, f = { ...d.next };
|
|
19
|
+
if (u === null) {
|
|
20
|
+
let { idToLayoutItem: e } = c;
|
|
21
|
+
f.idToLayoutItem = structuredClone(e);
|
|
22
|
+
}
|
|
23
|
+
let m = f.idToLayoutItem[t], { x: h, y: g } = l(n, e, c.idToLayoutItem[t]);
|
|
24
|
+
return f.idToLayoutItem = r(a(s(Object.values(f.idToLayoutItem), m, i(h, m, n), g, !0, !1))), {
|
|
25
|
+
...d,
|
|
26
|
+
movedId: t,
|
|
27
|
+
next: f,
|
|
28
|
+
extent: o(Object.values(f.idToLayoutItem))
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
case "ADD_CELL": {
|
|
32
|
+
let { coordinates: e, size: t } = p, { w: l, h: u } = t, { metrics: f, next: m, current: h, movedId: g } = d, { x: _, y: v } = c(f, e, t);
|
|
33
|
+
if (g === null) {
|
|
34
|
+
let { idToLayoutItem: e } = h;
|
|
35
|
+
m.idToLayoutItem = {
|
|
36
|
+
...structuredClone(e),
|
|
37
|
+
[n]: {
|
|
38
|
+
i: n,
|
|
39
|
+
x: _,
|
|
40
|
+
y: v,
|
|
41
|
+
w: l,
|
|
42
|
+
h: u
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
let y = m.idToLayoutItem[n];
|
|
47
|
+
return g !== null && y.x === _ && y.y === v ? d : (m.idToLayoutItem = r(a(s(Object.values(m.idToLayoutItem), y, i(_, y, f), v, !0, !1))), {
|
|
48
|
+
...d,
|
|
49
|
+
movedId: n,
|
|
50
|
+
next: m,
|
|
51
|
+
extent: o(Object.values(m.idToLayoutItem))
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
case "COMMIT_CHANGE": {
|
|
55
|
+
let { idToLayoutItem: e } = p;
|
|
56
|
+
return {
|
|
57
|
+
...d,
|
|
58
|
+
movedId: null,
|
|
59
|
+
current: { idToLayoutItem: e }
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
case "DRAG_ENTER": return {
|
|
63
|
+
...d,
|
|
64
|
+
dragIsOutside: !1,
|
|
65
|
+
movedId: null
|
|
66
|
+
};
|
|
67
|
+
case "DRAG_LEAVE": {
|
|
68
|
+
let { next: e, movedId: t } = d;
|
|
69
|
+
if (e.idToLayoutItem.__dropped__) {
|
|
70
|
+
let t = { ...e.idToLayoutItem };
|
|
71
|
+
delete t[n];
|
|
72
|
+
let i = r(a(Object.values(t)));
|
|
73
|
+
return {
|
|
74
|
+
...d,
|
|
75
|
+
movedId: null,
|
|
76
|
+
next: { idToLayoutItem: i },
|
|
77
|
+
extent: o(Object.values(i))
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (t) {
|
|
81
|
+
let n = { ...e.idToLayoutItem };
|
|
82
|
+
delete n[t];
|
|
83
|
+
let i = r(a(Object.values(n)));
|
|
84
|
+
return {
|
|
85
|
+
...d,
|
|
86
|
+
dragIsOutside: !0,
|
|
87
|
+
next: { idToLayoutItem: i },
|
|
88
|
+
extent: o(Object.values(i))
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return d;
|
|
92
|
+
}
|
|
93
|
+
case "DRAG_END": {
|
|
94
|
+
let { id: e, dragIsOutside: t, movedId: n, onRemove: r, next: { idToLayoutItem: i } } = d;
|
|
95
|
+
if (n !== null) {
|
|
96
|
+
if (t && n && r) {
|
|
97
|
+
let t = Object.values(i);
|
|
98
|
+
setTimeout(() => {
|
|
99
|
+
r(e, t, n, p.event);
|
|
100
|
+
}, 0);
|
|
101
|
+
let a = { ...d.idToChild };
|
|
102
|
+
return delete a[n], {
|
|
103
|
+
...d,
|
|
104
|
+
movedId: null,
|
|
105
|
+
current: { idToLayoutItem: i },
|
|
106
|
+
idToChild: a
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
...d,
|
|
111
|
+
movedId: null
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return d;
|
|
115
|
+
}
|
|
116
|
+
case "RESIZE": {
|
|
117
|
+
let { size: e, id: t } = p, { current: n, movedId: i } = d, c = { ...d.next };
|
|
118
|
+
if (i === null) {
|
|
119
|
+
let { idToLayoutItem: e } = n;
|
|
120
|
+
c.idToLayoutItem = structuredClone(e);
|
|
121
|
+
}
|
|
122
|
+
let l = c.idToLayoutItem[t];
|
|
123
|
+
return Object.assign(l, e), c.idToLayoutItem = r(a(s(Object.values(c.idToLayoutItem), l, l.x, l.y, !0, !1))), {
|
|
124
|
+
...d,
|
|
125
|
+
movedId: t,
|
|
126
|
+
next: c,
|
|
127
|
+
extent: o(Object.values(c.idToLayoutItem))
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
case "RESIZE_END": {
|
|
131
|
+
let { id: e, onLayoutChange: t, next: { idToLayoutItem: n } } = d;
|
|
132
|
+
return t && setTimeout(() => {
|
|
133
|
+
t(e, Object.values(n));
|
|
134
|
+
}, 0), {
|
|
135
|
+
...d,
|
|
136
|
+
current: { idToLayoutItem: n },
|
|
137
|
+
movedId: null
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
case "SYNC": {
|
|
141
|
+
let { layout: e, children: t, metrics: n } = p, i = r(e), a = u.toArray(t).reduce((e, t) => {
|
|
142
|
+
if (f(t)) {
|
|
143
|
+
let n = t.props["data-id"];
|
|
144
|
+
e[n] = t;
|
|
145
|
+
}
|
|
146
|
+
return e;
|
|
147
|
+
}, {}), s = o(e);
|
|
148
|
+
return {
|
|
149
|
+
...d,
|
|
150
|
+
id: p.id,
|
|
151
|
+
extent: s,
|
|
152
|
+
metrics: n,
|
|
153
|
+
idToChild: a,
|
|
154
|
+
current: { idToLayoutItem: i }
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
default: throw Error(`Unknown action type: ${m}`);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
//#endregion
|
|
161
|
+
export { m as DragDataStore, p as GridDispatch, h as gridLayoutReducer };
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=ReactGridLayoutReducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactGridLayoutReducer.js","names":[],"sources":["../src/ReactGridLayoutReducer.tsx"],"sourcesContent":["import { Children, createContext, isValidElement, type Dispatch, type DragEvent } from 'react'\nimport { LEVELS, log } from './logs'\nimport { NEW_ITEM_ID, type ChildById, type DimensionsType, type Extent, type GridLayoutById, type GridMetrics, type LayoutChangeHandler, type LayoutItemType, type PointType, type RemoveHandler } from './types'\nimport { byId, clampX, compact, getExtent, moveElement, toGridCoordinates, toGridCoordinates2 } from './utils'\n\nexport type GridLayoutAction =\n | {\n type: 'SYNC',\n id: string,\n layout: LayoutItemType[],\n children: React.ReactNode,\n metrics: GridMetrics\n }\n | {\n type: 'MOVE_CELL',\n delta: PointType,\n id: string\n }\n | {\n type: 'ADD_CELL',\n coordinates: PointType,\n size: DimensionsType\n }\n | {\n type: 'DRAG_ENTER'\n }\n | {\n type: 'DRAG_LEAVE'\n }\n | {\n type: 'DRAG_END',\n id: string\n event: DragEvent<HTMLElement>\n }\n | {\n type: 'COMMIT_CHANGE',\n idToLayoutItem: GridLayoutById\n }\n | {\n type: 'RESIZE',\n id: string,\n size: DimensionsType\n }\n | {\n type: 'RESIZE_END'\n }\n | {\n type: 'SET_PO',\n p0: PointType\n }\nexport const GridDispatch = createContext<Dispatch<GridLayoutAction> | null>(null)\n\n/**\n * Interface for the drag data store used to bypass the drag-end-drop protected mode\n */\nexport interface DragStoreType {\n [key: string]: any\n}\n/**\n * A context to store a drag data store which is available throughout the API\n * and bypasses drag-end-drop protected mode\n */\nexport const DragDataStore = createContext<DragStoreType>({})\n\nexport interface GridLayoutState {\n id: string,\n metrics: GridMetrics,\n extent: Extent,\n idToChild: ChildById,\n current: {\n idToLayoutItem: GridLayoutById,\n }\n next: {\n idToLayoutItem: GridLayoutById,\n }\n movedId: string | null,\n dragIsOutside: boolean,\n onRemove: RemoveHandler | undefined,\n onLayoutChange: LayoutChangeHandler | undefined,\n p0: PointType | null\n}\n\n/**\n * GridLayout reducer\n * Implementation notes\n *\n * Implementation must workaround https://bugzilla.mozilla.org/show_bug.cgi?id=460801\n * so DOM nodes must not be removed during an operation, otherwise dragEnd will never be fired\n *\n * Because of DND protected mode, one cannot query the data during onDragOver, hence the use\n * of a datastore context object as a more permissive substitute to the DND datastore\n *\n * Changes are meant to be transactional: during an interaction, the temporary new layout\n * is store in the 'next' property\n *\n * Layout change scenario\n * The actual react node is hidden and replaced by its DND drag ghost. A temporary placeholder\n * child is created to materialize the spot of the moved node in the new layout\n *\n * Child removal scenario\n * The actual react node is hidden and replaced by its DND drag ghost. No temporary placeholder\n * child gets created since the drag occurs outside of the grid boundaries\n *\n * Add child scenario\n * A new temporary item with id NEW_ITEM_ID is created. The DND drag ghost represents the new item.\n * A temporary placeholder child is created to materialize the spot of the item in the new layout\n *\n * Resize scenario\n * A temporary placeholder child is created to materialize the spot of the resized node in the new layout\n */\nexport const gridLayoutReducer = (state: GridLayoutState, action: GridLayoutAction): GridLayoutState => {\n log('gridLayoutReducer', LEVELS.INFO, state, action)\n const { type } = action\n switch (type) {\n case 'SET_PO': {\n const { p0 } = action\n return { ...state, p0 }\n }\n\n case 'MOVE_CELL': {\n const { delta, id } = action\n const { metrics, current, movedId } = state\n const next = { ...state.next }\n if (movedId === null) {\n const { idToLayoutItem } = current\n next.idToLayoutItem = structuredClone(idToLayoutItem)\n }\n const item = next.idToLayoutItem[id]\n const { x, y } = toGridCoordinates2(metrics, delta, current.idToLayoutItem[id])\n next.idToLayoutItem = byId(\n compact(\n moveElement(\n Object.values(next.idToLayoutItem),\n item,\n clampX(x, item, metrics),\n y,\n true,\n false\n )\n )\n )\n return {\n ...state,\n movedId: id,\n next,\n extent: getExtent(Object.values(next.idToLayoutItem))\n }\n }\n\n case 'ADD_CELL': {\n const { coordinates, size } = action\n const { w, h } = size\n const { metrics, next, current, movedId } = state\n const { x, y } = toGridCoordinates(metrics, coordinates, size)\n if (movedId === null) {\n const { idToLayoutItem } = current\n next.idToLayoutItem = {\n ...structuredClone(idToLayoutItem),\n [NEW_ITEM_ID]: {\n i: NEW_ITEM_ID,\n x,\n y,\n w,\n h\n }\n }\n }\n const item = next.idToLayoutItem[NEW_ITEM_ID]\n if (movedId !== null && item.x === x && item.y === y) {\n return state\n }\n next.idToLayoutItem = byId(\n compact(\n moveElement(\n Object.values(next.idToLayoutItem),\n item,\n clampX(x, item, metrics),\n y,\n true,\n false\n )\n )\n )\n return {\n ...state,\n movedId: NEW_ITEM_ID,\n next,\n extent: getExtent(Object.values(next.idToLayoutItem))\n }\n }\n\n case 'COMMIT_CHANGE': {\n const { idToLayoutItem } = action\n return { ...state, movedId: null, current: { idToLayoutItem } }\n }\n\n case 'DRAG_ENTER': {\n return {\n ...state,\n dragIsOutside: false,\n movedId: null\n }\n }\n\n case 'DRAG_LEAVE': {\n const { next, movedId } = state\n if (next.idToLayoutItem[NEW_ITEM_ID]) {\n const idToLayoutItem = { ...next.idToLayoutItem }\n delete idToLayoutItem[NEW_ITEM_ID]\n const idToLayoutItem_ = byId(\n compact(\n Object.values(idToLayoutItem)\n )\n )\n return {\n ...state,\n movedId: null,\n next: {\n idToLayoutItem: idToLayoutItem_,\n },\n extent: getExtent(Object.values(idToLayoutItem_)),\n }\n }\n if (movedId) {\n const idToLayoutItem = { ...next.idToLayoutItem }\n delete idToLayoutItem[movedId]\n const idToLayoutItem_ = byId(\n compact(\n Object.values(idToLayoutItem)\n )\n )\n return {\n ...state,\n dragIsOutside: true,\n next: {\n idToLayoutItem: idToLayoutItem_,\n },\n extent: getExtent(Object.values(idToLayoutItem_)),\n }\n }\n return state\n }\n\n case 'DRAG_END': {\n const { id, dragIsOutside, movedId, onRemove, next: { idToLayoutItem } } = state\n if (movedId !== null) {\n if (dragIsOutside && movedId && onRemove) {\n const layout = Object.values(idToLayoutItem)\n setTimeout(() => {\n onRemove(id, layout, movedId, action.event)\n }, 0)\n const idToChild = { ...state.idToChild }\n delete idToChild[movedId]\n return { ...state, movedId: null, current: { idToLayoutItem }, idToChild }\n }\n return { ...state, movedId: null }\n }\n return state\n }\n\n case 'RESIZE': {\n const { size, id } = action\n const { current, movedId } = state\n const next = { ...state.next }\n if (movedId === null) {\n const { idToLayoutItem } = current\n next.idToLayoutItem = structuredClone(idToLayoutItem)\n }\n const item = next.idToLayoutItem[id]\n Object.assign(item, size)\n next.idToLayoutItem = byId(\n compact(\n moveElement(\n Object.values(next.idToLayoutItem),\n item,\n item.x,\n item.y,\n true,\n false\n )\n )\n )\n return {\n ...state,\n movedId: id,\n next,\n extent: getExtent(Object.values(next.idToLayoutItem))\n }\n }\n\n case 'RESIZE_END': {\n const { id, onLayoutChange, next: { idToLayoutItem } } = state\n if (onLayoutChange) {\n setTimeout(() => {\n onLayoutChange(id, Object.values(idToLayoutItem))\n }, 0)\n }\n return { ...state, current: { idToLayoutItem }, movedId: null }\n }\n\n case 'SYNC': {\n const {\n layout,\n children,\n metrics,\n } = action\n const idToLayoutItem = byId(layout)\n const idToChild = Children.toArray(children).reduce<ChildById>((acc, child) => {\n if (isValidElement(child)) {\n const id = child.props['data-id']\n acc[id] = child\n }\n return acc\n }, {})\n const extent = getExtent(layout)\n return {\n ...state,\n id: action.id,\n extent,\n metrics,\n idToChild,\n current: {\n idToLayoutItem,\n },\n }\n }\n\n default: {\n throw new Error(`Unknown action type: ${type}`)\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
.react-grid-item{transition:transform .2s}.react-grid-placeholder{opacity:.2;z-index:2;-webkit-user-select:none;user-select:none;-o-user-select:none;background:red;transition-duration:.1s;position:absolute;inset:0}.react-resizable{position:relative}.react-resizable-handle{box-sizing:border-box;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2IDYiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iNnB4Ij48ZyBvcGFjaXR5PSIwLjMwMiI+PHBhdGggZD0iTSA2IDYgTCAwIDYgTCAwIDQuMiBMIDQgNC4yIEwgNC4yIDQuMiBMIDQuMiAwIEwgNiAwIEwgNiA2IEwgNiA2IFoiIGZpbGw9IiMwMDAwMDAiLz48L2c+PC9zdmc+);background-position:100% 100%;background-repeat:no-repeat;background-origin:content-box;width:20px;height:20px;padding:0 3px 3px 0;position:absolute}.react-resizable-handle-sw{cursor:sw-resize;bottom:0;left:0;transform:rotate(90deg)}.react-resizable-handle-se{cursor:se-resize;bottom:0;right:0}.react-resizable-handle-nw{cursor:nw-resize;top:0;left:0;transform:rotate(180deg)}.react-resizable-handle-ne{cursor:ne-resize;top:0;right:0;transform:rotate(270deg)}.react-resizable-handle-w,.react-resizable-handle-e{cursor:ew-resize;margin-top:-10px;top:50%}.react-resizable-handle-w{left:0;transform:rotate(135deg)}.react-resizable-handle-e{right:0;transform:rotate(315deg)}.react-resizable-handle-n,.react-resizable-handle-s{cursor:ns-resize;margin-left:-10px;left:50%}.react-resizable-handle-n{top:0;transform:rotate(225deg)}.react-resizable-handle-s{bottom:0;transform:rotate(45deg)}.react-grid-layout{will-change:height;transition:height .2s;display:block;position:relative}
|
|
2
|
+
/*$vite$:1*/
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { Context } from 'react';
|
|
2
|
+
import { DragEvent as DragEvent_2 } from 'react';
|
|
3
|
+
import { FunctionComponent } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Callback function invoked a new item is added to the grid layout
|
|
7
|
+
*/
|
|
8
|
+
export declare type AddHandler = (id: string, layout: LayoutItemType[], droppedItemIndex: number, event: DragEvent_2<HTMLElement>) => void;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Function to transform an array of layout items
|
|
12
|
+
* into a dictionary of layout items (using the item id as the key)
|
|
13
|
+
*/
|
|
14
|
+
export declare const byId: (layout: LayoutItemType[]) => GridLayoutById;
|
|
15
|
+
|
|
16
|
+
declare interface DimensionsType {
|
|
17
|
+
w: number;
|
|
18
|
+
h: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A context to store a drag data store which is available throughout the API
|
|
23
|
+
* and bypasses drag-end-drop protected mode
|
|
24
|
+
*/
|
|
25
|
+
export declare const DragDataStore: Context<DragStoreType>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Callback function invoked a droppable item is dragged over the grid layout.
|
|
29
|
+
* If the grid layout accepts the item, it should return the size the new item
|
|
30
|
+
* will have in the layout. If the grid layout rejects the item, it must return 'undefined'.
|
|
31
|
+
*/
|
|
32
|
+
export declare type DragOverHandler = (id: string, event: DragEvent_2<HTMLElement>) => DimensionsType | undefined;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Interface for the drag data store used to bypass the drag-end-drop protected mode
|
|
36
|
+
*/
|
|
37
|
+
export declare interface DragStoreType {
|
|
38
|
+
[key: string]: any;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Custom MIME type for grid to grid drag-and-drop operations
|
|
43
|
+
*/
|
|
44
|
+
export declare const GRID_MIME_TYPE = "x-com.dassault_systemes.grid+json";
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A reactive, fluid grid layout with draggable, resizable components.
|
|
48
|
+
* The grid supports the following operations:
|
|
49
|
+
* Re-arranging its children by dragging them to their new position (triggers onLayoutChange)
|
|
50
|
+
* Resizing its children using their resize handles (triggers onLayoutChange)
|
|
51
|
+
* Remove one of its children, by dragging it outside the grid boundaries (triggers onRemove)
|
|
52
|
+
* Accepting (by implementing onDragOver) new children from drag and drop (triggers onAdd) ;
|
|
53
|
+
* these new children may come from another grid (in this case, onRemove in called on
|
|
54
|
+
* the source grid and onAdd in called on the destination grid)
|
|
55
|
+
*/
|
|
56
|
+
export declare const GridLayout: FunctionComponent<GridLayoutProps>;
|
|
57
|
+
|
|
58
|
+
declare interface GridLayoutById {
|
|
59
|
+
[key: string]: LayoutItemType;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Grid component with draggable and resizable cells.
|
|
64
|
+
* Grid cells use absolute positionning
|
|
65
|
+
* The cells in the grid a defined by the 'children' and the 'layout' properties.
|
|
66
|
+
* The association between child nodes and layout info is guaranteed by
|
|
67
|
+
* a 'data-id' DOM attribute on child nodes (its value must match the id of the
|
|
68
|
+
* corresponding LayoutItemType object)
|
|
69
|
+
*/
|
|
70
|
+
export declare interface GridLayoutProps {
|
|
71
|
+
/**
|
|
72
|
+
* Grid unique identifier
|
|
73
|
+
*/
|
|
74
|
+
id: string;
|
|
75
|
+
/**
|
|
76
|
+
* An array of react nodes to populate grid cells
|
|
77
|
+
*/
|
|
78
|
+
children: React.ReactNode;
|
|
79
|
+
/**
|
|
80
|
+
* An array of grid cell attributes
|
|
81
|
+
*/
|
|
82
|
+
layout: LayoutItemType[];
|
|
83
|
+
/**
|
|
84
|
+
* Pixel width of the grid
|
|
85
|
+
*/
|
|
86
|
+
width: number;
|
|
87
|
+
/**
|
|
88
|
+
* Number of columns of the grid
|
|
89
|
+
*/
|
|
90
|
+
cols: number;
|
|
91
|
+
/**
|
|
92
|
+
* Height of a widget row
|
|
93
|
+
*/
|
|
94
|
+
rowHeight: number;
|
|
95
|
+
/**
|
|
96
|
+
* Minimum height of the widget grid (if the grid does not contain any cell)
|
|
97
|
+
*/
|
|
98
|
+
minHeight?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Horizonal padding between the grid border and its content cells
|
|
101
|
+
*/
|
|
102
|
+
paddingX?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Vertical padding between the grid border and its content cells
|
|
105
|
+
*/
|
|
106
|
+
paddingY?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Horizonal margin between adjacent cells
|
|
109
|
+
*/
|
|
110
|
+
marginX?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Vertical margin between adjacent cells
|
|
113
|
+
*/
|
|
114
|
+
marginY?: number;
|
|
115
|
+
/**
|
|
116
|
+
* Optional CSS classname
|
|
117
|
+
*/
|
|
118
|
+
className?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Optional style
|
|
121
|
+
*/
|
|
122
|
+
style?: React.CSSProperties;
|
|
123
|
+
/**
|
|
124
|
+
* True if grid elements can be dragged around
|
|
125
|
+
* (defaults to true)
|
|
126
|
+
*/
|
|
127
|
+
isDraggable?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* True if grid elements can be resized
|
|
130
|
+
* (defaults to true)
|
|
131
|
+
*/
|
|
132
|
+
isResizable?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* True if grid accepts dnd elements
|
|
135
|
+
* (defaults to true)
|
|
136
|
+
*/
|
|
137
|
+
isDroppable?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Invoked when the layout is updated.
|
|
140
|
+
* This handler is not invoked during user interactions,
|
|
141
|
+
* only at the end of completed interactions (once the layout has actually
|
|
142
|
+
* changed)
|
|
143
|
+
*/
|
|
144
|
+
onLayoutChange?: LayoutChangeHandler;
|
|
145
|
+
onAdd?: AddHandler;
|
|
146
|
+
onRemove?: RemoveHandler;
|
|
147
|
+
onDragOver?: DragOverHandler;
|
|
148
|
+
/**
|
|
149
|
+
* Optional max number of rows
|
|
150
|
+
*/
|
|
151
|
+
maxRows?: number;
|
|
152
|
+
/**
|
|
153
|
+
* True if cells can be dragged beyond
|
|
154
|
+
* the current grid size (defaults to false)
|
|
155
|
+
*/
|
|
156
|
+
isBounded?: boolean;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Interface for grid to grid drag-and-drop operations
|
|
161
|
+
*/
|
|
162
|
+
export declare interface GridMoveOperation {
|
|
163
|
+
/**
|
|
164
|
+
* Operation type
|
|
165
|
+
*/
|
|
166
|
+
operation: 'move';
|
|
167
|
+
/**
|
|
168
|
+
* Id of the grid acting as the source of the drag operation
|
|
169
|
+
*/
|
|
170
|
+
gridId: string;
|
|
171
|
+
/**
|
|
172
|
+
* Id of the cell being dragged in the source grid
|
|
173
|
+
*/
|
|
174
|
+
id: string;
|
|
175
|
+
/**
|
|
176
|
+
* Size of of the cell being dragged in the source grid
|
|
177
|
+
*/
|
|
178
|
+
size: DimensionsType;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Callback function invoked when the grid layout changes
|
|
183
|
+
*/
|
|
184
|
+
export declare type LayoutChangeHandler = (id: string, layout: LayoutItemType[]) => void;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Interface to represent a grid cell
|
|
188
|
+
*/
|
|
189
|
+
export declare interface LayoutItemType {
|
|
190
|
+
/**
|
|
191
|
+
* unique cell identifier
|
|
192
|
+
*/
|
|
193
|
+
i: string;
|
|
194
|
+
/**
|
|
195
|
+
* x in grid coordinates
|
|
196
|
+
*/
|
|
197
|
+
x: number;
|
|
198
|
+
/**
|
|
199
|
+
* u in grid coordinates
|
|
200
|
+
*/
|
|
201
|
+
y: number;
|
|
202
|
+
/**
|
|
203
|
+
* width in grid coordinates
|
|
204
|
+
*/
|
|
205
|
+
w: number;
|
|
206
|
+
/**
|
|
207
|
+
* height in grid coordinates
|
|
208
|
+
*/
|
|
209
|
+
h: number;
|
|
210
|
+
/**
|
|
211
|
+
* optional max width
|
|
212
|
+
*/
|
|
213
|
+
maxW?: number;
|
|
214
|
+
/**
|
|
215
|
+
* optional max height
|
|
216
|
+
*/
|
|
217
|
+
maxH?: number;
|
|
218
|
+
/**
|
|
219
|
+
* optional min width
|
|
220
|
+
*/
|
|
221
|
+
minW?: number;
|
|
222
|
+
/**
|
|
223
|
+
* optional min height
|
|
224
|
+
*/
|
|
225
|
+
minH?: number;
|
|
226
|
+
/**
|
|
227
|
+
* true if the cell can be dragged
|
|
228
|
+
*/
|
|
229
|
+
isDraggable?: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* true if the cell can be resized
|
|
232
|
+
*/
|
|
233
|
+
isResizable?: boolean;
|
|
234
|
+
/**
|
|
235
|
+
* true if the call must stay at this location
|
|
236
|
+
*/
|
|
237
|
+
static?: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Temporary
|
|
240
|
+
*/
|
|
241
|
+
moved?: boolean;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Object to control logs
|
|
246
|
+
*/
|
|
247
|
+
export declare const Logs: LogsType;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Interface to activate logs for debugging purposes.
|
|
251
|
+
* The keys are the name of trace to activate.
|
|
252
|
+
* The value is a log level. There are 3 levels of traces:
|
|
253
|
+
* <dl>
|
|
254
|
+
* <dt>0</dt>
|
|
255
|
+
* <dd>errors</dd>
|
|
256
|
+
* <dt>1</dt>
|
|
257
|
+
* <dd>info</dd>
|
|
258
|
+
* <dt>2</dt>
|
|
259
|
+
* <dd>debug</dd>
|
|
260
|
+
* </dl>
|
|
261
|
+
*/
|
|
262
|
+
declare type LogsType = {
|
|
263
|
+
[key: string]: number;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Callback function invoked an item is removed from the grid layout
|
|
268
|
+
*/
|
|
269
|
+
export declare type RemoveHandler = (id: string, layout: LayoutItemType[], removedId: string, event: DragEvent_2<HTMLElement>) => void;
|
|
270
|
+
|
|
271
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Logs as e } from "./logs.js";
|
|
2
|
+
import { GRID_MIME_TYPE as t } from "./types.js";
|
|
3
|
+
import { byId as n } from "./utils.js";
|
|
4
|
+
import { DragDataStore as r } from "./ReactGridLayoutReducer.js";
|
|
5
|
+
import { GridLayout as i } from "./ReactGridLayout.js";
|
|
6
|
+
export { r as DragDataStore, t as GRID_MIME_TYPE, i as GridLayout, e as Logs, n as byId };
|
package/dist/logs.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/logs.ts
|
|
2
|
+
var e = {
|
|
3
|
+
ERROR: 0,
|
|
4
|
+
INFO: 1,
|
|
5
|
+
DEBUG: 2
|
|
6
|
+
}, t = {
|
|
7
|
+
GridItem: 0,
|
|
8
|
+
GridLayout: 0,
|
|
9
|
+
gridLayoutReducer: 0,
|
|
10
|
+
compact: 0,
|
|
11
|
+
moveElement: 0,
|
|
12
|
+
moveElementAwayFromCollision: 0,
|
|
13
|
+
PlaceHolder: 0
|
|
14
|
+
}, n = (e, n, ...r) => {
|
|
15
|
+
let i = t[e];
|
|
16
|
+
typeof i == "number" && n <= i && console.log(e, ...r);
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { e as LEVELS, t as Logs, n as log };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=logs.js.map
|
package/dist/logs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","names":[],"sources":["../src/logs.ts"],"sourcesContent":["export const LEVELS = {\n ERROR: 0,\n INFO: 1,\n DEBUG: 2\n}\n\n/**\n * Interface to activate logs for debugging purposes.\n * The keys are the name of trace to activate.\n * The value is a log level. There are 3 levels of traces:\n * <dl>\n * <dt>0</dt>\n * <dd>errors</dd>\n * <dt>1</dt>\n * <dd>info</dd>\n * <dt>2</dt>\n * <dd>debug</dd>\n * </dl>\n */\ntype LogsType = {\n [key: string]: number\n}\n\n/**\n * Object to control logs\n */\nexport const Logs: LogsType = {\n GridItem: 0,\n GridLayout: 0,\n gridLayoutReducer: 0,\n compact: 0,\n moveElement: 0,\n moveElementAwayFromCollision: 0,\n PlaceHolder: 0\n}\n\nexport const log = (facility: string, severity: number, ...args: any[]) => {\n const sev = Logs[facility]\n if (typeof sev === 'number' && severity <= sev) {\n console.log(facility, ...args)\n }\n}\n"],"mappings":";AAAA,IAAa,IAAS;CACpB,OAAO;CACP,MAAM;CACN,OAAO;AACT,GAsBa,IAAiB;CAC5B,UAAU;CACV,YAAY;CACZ,mBAAmB;CACnB,SAAS;CACT,aAAa;CACb,8BAA8B;CAC9B,aAAa;AACf,GAEa,KAAO,GAAkB,GAAkB,GAAG,MAAgB;CACzE,IAAM,IAAM,EAAK;CACjB,AAAI,OAAO,KAAQ,YAAY,KAAY,KACzC,QAAQ,IAAI,GAAU,GAAG,CAAI;AAEjC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["import type { DragEvent } from 'react'\n\n/**\n * Interface to represent a grid cell\n */\nexport interface LayoutItemType {\n /**\n * unique cell identifier\n */\n i: string,\n /**\n * x in grid coordinates\n */\n x: number,\n /**\n * u in grid coordinates\n */\n y: number,\n /**\n * width in grid coordinates\n */\n w: number,\n /**\n * height in grid coordinates\n */\n h: number,\n /**\n * optional max width\n */\n maxW?: number,\n /**\n * optional max height\n */\n maxH?: number,\n /**\n * optional min width\n */\n minW?: number,\n /**\n * optional min height\n */\n minH?: number,\n /**\n * true if the cell can be dragged\n */\n isDraggable?: boolean,\n /**\n * true if the cell can be resized\n */\n isResizable?: boolean,\n /**\n * true if the call must stay at this location\n */\n static?: boolean\n /**\n * Temporary\n */\n moved?: boolean\n}\n\n/**\n * The grid extend\n */\nexport interface Extent {\n xMax: number,\n yMax: number\n}\n\nexport interface DimensionsType {\n w: number,\n h: number\n}\n\nexport interface PointType {\n x: number,\n y: number,\n}\n\nexport interface GridLayoutById {\n [key: string]: LayoutItemType\n}\n\nexport interface ChildById {\n [key: string]: React.ReactNode\n}\n\n/**\n * Callback function invoked when the grid layout changes\n */\nexport type LayoutChangeHandler = (id: string, layout: LayoutItemType[]) => void\n/**\n * Callback function invoked a new item is added to the grid layout\n */\nexport type AddHandler = (id: string, layout: LayoutItemType[], droppedItemIndex: number, event: DragEvent<HTMLElement>) => void\n/**\n * Callback function invoked an item is removed from the grid layout\n */\nexport type RemoveHandler = (id: string, layout: LayoutItemType[], removedId: string, event: DragEvent<HTMLElement>) => void\n/**\n * Callback function invoked a droppable item is dragged over the grid layout.\n * If the grid layout accepts the item, it should return the size the new item\n * will have in the layout. If the grid layout rejects the item, it must return 'undefined'.\n */\nexport type DragOverHandler = (id: string, event: DragEvent<HTMLElement>) => DimensionsType | undefined\n\n/**\n * Grid component with draggable and resizable cells.\n * Grid cells use absolute positionning\n * The cells in the grid a defined by the 'children' and the 'layout' properties.\n * The association between child nodes and layout info is guaranteed by\n * a 'data-id' DOM attribute on child nodes (its value must match the id of the\n * corresponding LayoutItemType object)\n */\nexport interface GridLayoutProps {\n /**\n * Grid unique identifier\n */\n id: string,\n /**\n * An array of react nodes to populate grid cells\n */\n children: React.ReactNode,\n /**\n * An array of grid cell attributes\n */\n layout: LayoutItemType[],\n /**\n * Pixel width of the grid\n */\n width: number,\n /**\n * Number of columns of the grid\n */\n cols: number,\n /**\n * Height of a widget row\n */\n rowHeight: number,\n /**\n * Minimum height of the widget grid (if the grid does not contain any cell)\n */\n minHeight?: number,\n /**\n * Horizonal padding between the grid border and its content cells\n */\n paddingX?: number,\n /**\n * Vertical padding between the grid border and its content cells\n */\n paddingY?: number,\n /**\n * Horizonal margin between adjacent cells\n */\n marginX?: number,\n /**\n * Vertical margin between adjacent cells\n */\n marginY?: number,\n /**\n * Optional CSS classname\n */\n className?: string,\n /**\n * Optional style\n */\n style?: React.CSSProperties,\n /**\n * True if grid elements can be dragged around\n * (defaults to true)\n */\n isDraggable?: boolean,\n /**\n * True if grid elements can be resized\n * (defaults to true)\n */\n isResizable?: boolean,\n /**\n * True if grid accepts dnd elements\n * (defaults to true)\n */\n isDroppable?: boolean,\n /**\n * Invoked when the layout is updated.\n * This handler is not invoked during user interactions,\n * only at the end of completed interactions (once the layout has actually\n * changed)\n */\n onLayoutChange?: LayoutChangeHandler,\n onAdd?: AddHandler,\n onRemove?: RemoveHandler,\n onDragOver?: DragOverHandler,\n /**\n * Optional max number of rows\n */\n maxRows?: number,\n /**\n * True if cells can be dragged beyond\n * the current grid size (defaults to false)\n */\n isBounded?: boolean,\n}\n\nexport interface GridMetrics {\n id: string,\n cols: number,\n rowHeight: number,\n width: number,\n marginX: number,\n marginY: number\n paddingX: number,\n paddingY: number,\n isDraggable: boolean,\n isResizable: boolean,\n div: HTMLDivElement | null\n}\n\n/**\n * Interface for grid to grid drag-and-drop operations\n */\nexport interface GridMoveOperation {\n /**\n * Operation type\n */\n operation: 'move',\n /**\n * Id of the grid acting as the source of the drag operation\n */\n gridId: string,\n /**\n * Id of the cell being dragged in the source grid\n */\n id: string,\n /**\n * Size of of the cell being dragged in the source grid\n */\n size: DimensionsType\n}\n\n/**\n * Custom MIME type for grid to grid drag-and-drop operations\n */\nexport const GRID_MIME_TYPE = 'x-com.dassault_systemes.grid+json'\nexport const NEW_ITEM_ID = '__dropped__'\n"],"mappings":";AAiPA,IAAa,IAAiB,qCACjB,IAAc"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { LEVELS as e, log as t } from "./logs.js";
|
|
2
|
+
import "./types.js";
|
|
3
|
+
//#region src/utils.ts
|
|
4
|
+
function n(e, t, n) {
|
|
5
|
+
return Math.max(Math.min(e, n), t);
|
|
6
|
+
}
|
|
7
|
+
var r = (e) => e.reduce((e, t) => {
|
|
8
|
+
let { i: n } = t;
|
|
9
|
+
return e[n] = t, e;
|
|
10
|
+
}, {}), i = (e) => {
|
|
11
|
+
let { width: t, cols: n, paddingX: r } = e;
|
|
12
|
+
return (t - 2 * r) / n;
|
|
13
|
+
}, a = (e) => {
|
|
14
|
+
let { width: t, cols: n, marginX: r, paddingX: i } = e;
|
|
15
|
+
return r + (t - 2 * i - r * (n - 1)) / n;
|
|
16
|
+
}, o = (e) => {
|
|
17
|
+
let { rowHeight: t, marginY: n } = e;
|
|
18
|
+
return t + n;
|
|
19
|
+
}, s = (e, t) => {
|
|
20
|
+
let { w: n, h: r } = t, { width: i, rowHeight: a, cols: o, marginX: s, marginY: c, paddingX: l } = e;
|
|
21
|
+
return {
|
|
22
|
+
w: n * ((i - 2 * l - s * (o - 1)) / o) + (n - 1) * s,
|
|
23
|
+
h: r * a + (r - 1) * c
|
|
24
|
+
};
|
|
25
|
+
}, c = (e, t, n) => {
|
|
26
|
+
let { x: r, y: i } = t, { paddingX: s, paddingY: c } = e, l = a(e), u = o(e), { w: d, h: f } = n;
|
|
27
|
+
return {
|
|
28
|
+
position: "absolute",
|
|
29
|
+
width: `${d}px`,
|
|
30
|
+
height: `${f}px`,
|
|
31
|
+
transform: `translate(${s + r * l}px, ${c + i * u}px)`
|
|
32
|
+
};
|
|
33
|
+
}, l = (e, t, n) => {
|
|
34
|
+
let r = {
|
|
35
|
+
x: 0,
|
|
36
|
+
y: 0
|
|
37
|
+
}, { w: a, h: s } = n, { paddingX: c, paddingY: l, div: u } = e;
|
|
38
|
+
if (u) {
|
|
39
|
+
let n = i(e), d = o(e), { x: f, y: p } = u.getBoundingClientRect();
|
|
40
|
+
r.x = Math.ceil((t.x - (f + c) - .5 * n * a) / n), r.y = Math.ceil((t.y - (p + l) - .5 * d * s) / d);
|
|
41
|
+
}
|
|
42
|
+
return r;
|
|
43
|
+
}, u = (e, t, n) => {
|
|
44
|
+
let r = {
|
|
45
|
+
x: 0,
|
|
46
|
+
y: 0
|
|
47
|
+
}, i = a(e), s = o(e);
|
|
48
|
+
return r.x = Math.ceil((n.x * i - .5 * i + t.x) / i), r.y = Math.ceil((n.y * s - .5 * s + t.y) / s), r;
|
|
49
|
+
}, d = (e) => e.reduce((e, t) => {
|
|
50
|
+
let { x: n, y: r, w: i, h: a } = t;
|
|
51
|
+
return e.xMax = Math.max(e.xMax, n + i), e.yMax = Math.max(e.yMax, r + a), e;
|
|
52
|
+
}, {
|
|
53
|
+
xMax: 0,
|
|
54
|
+
yMax: 0
|
|
55
|
+
}), f = (e) => {
|
|
56
|
+
let { paddingY: t, marginY: n, rowHeight: r, yMax: i, minHeight: a } = e;
|
|
57
|
+
return Math.max(a, i * r + n * (i - 1) + 2 * t);
|
|
58
|
+
}, p = (e, t, n) => {
|
|
59
|
+
let { cols: r } = n, { w: i } = t;
|
|
60
|
+
return e + i < r ? e : r - i;
|
|
61
|
+
};
|
|
62
|
+
function m(e, t) {
|
|
63
|
+
return !(e.i === t.i || e.x + e.w <= t.x || e.x >= t.x + t.w || e.y + e.h <= t.y || e.y >= t.y + t.h);
|
|
64
|
+
}
|
|
65
|
+
function h(e, t) {
|
|
66
|
+
for (let n = 0, r = e.length; n < r; n++) if (m(e[n], t)) return e[n];
|
|
67
|
+
}
|
|
68
|
+
function g(e, t) {
|
|
69
|
+
return e.filter((e) => m(e, t));
|
|
70
|
+
}
|
|
71
|
+
function _(e) {
|
|
72
|
+
return e.slice(0).sort(function(e, t) {
|
|
73
|
+
return e.x > t.x || e.x === t.x && e.y > t.y ? 1 : -1;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function v(e) {
|
|
77
|
+
return e.filter((e) => e.static);
|
|
78
|
+
}
|
|
79
|
+
function y(n) {
|
|
80
|
+
t("compact", e.INFO, n);
|
|
81
|
+
let r = v(n), i = _(n), a = Array(n.length);
|
|
82
|
+
for (let e = 0, t = i.length; e < t; e++) {
|
|
83
|
+
let t = { ...i[e] };
|
|
84
|
+
t.static || (t = x(r, t, i), r.push(t)), a[n.indexOf(i[e])] = t, t.moved = !1;
|
|
85
|
+
}
|
|
86
|
+
return a;
|
|
87
|
+
}
|
|
88
|
+
function b(e, t, n) {
|
|
89
|
+
t.y += 1;
|
|
90
|
+
let r = e.findIndex((e) => e.i === t.i);
|
|
91
|
+
for (let i = r + 1, a = e.length; i < a; i++) {
|
|
92
|
+
let r = e[i];
|
|
93
|
+
if (!r.static) {
|
|
94
|
+
if (r.y > t.y + t.h) break;
|
|
95
|
+
m(t, r) && b(e, r, n + t.h);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
t.y = n;
|
|
99
|
+
}
|
|
100
|
+
function x(e, t, n) {
|
|
101
|
+
for (t.y = Math.min(d(e).yMax, t.y); t.y > 0 && !h(e, t);) t.y--;
|
|
102
|
+
let r;
|
|
103
|
+
for (; r = h(e, t);) b(n, t, r.y + r.h);
|
|
104
|
+
return t.y = Math.max(t.y, 0), t.x = Math.max(t.x, 0), t;
|
|
105
|
+
}
|
|
106
|
+
var S = (n, r, i, a, o, s) => {
|
|
107
|
+
if (r.static && r.isDraggable !== !0 || r.y === a && r.x === i) return n;
|
|
108
|
+
t("moveElement", e.DEBUG, `Moving element "${r.i}"@[${r.x},${r.y}] => [${i},${a}]`);
|
|
109
|
+
let c = r.x, l = r.y;
|
|
110
|
+
typeof i == "number" && (r.x = i), typeof a == "number" && (r.y = a), r.moved = !0;
|
|
111
|
+
let u = _(n);
|
|
112
|
+
typeof a == "number" && l >= a && (u = u.reverse());
|
|
113
|
+
let d = g(u, r);
|
|
114
|
+
if (d.length > 0 && s) return t("moveElement", e.DEBUG, `Collision prevented on ${r.i}, reverting.`), r.x = c, r.y = l, r.moved = !1, n;
|
|
115
|
+
for (let i = 0, a = d.length; i < a; i++) {
|
|
116
|
+
let a = d[i];
|
|
117
|
+
t("moveElement", e.DEBUG, `Resolving collision between "${r.i}"@[${r.x},${r.y}] and "${a.i}"@[${a.x},${a.y}]`), !a.moved && (n = a.static ? C(n, a, r, o) : C(n, r, a, o));
|
|
118
|
+
}
|
|
119
|
+
return n;
|
|
120
|
+
}, C = (n, r, i, a) => {
|
|
121
|
+
let o = r.static;
|
|
122
|
+
if (a) {
|
|
123
|
+
a = !1;
|
|
124
|
+
let s = {
|
|
125
|
+
x: i.x,
|
|
126
|
+
y: Math.max(r.y - i.h, 0),
|
|
127
|
+
w: i.w,
|
|
128
|
+
h: i.h,
|
|
129
|
+
i: "-1"
|
|
130
|
+
}, c = h(n, s), l = c && c.y + c.h > r.y;
|
|
131
|
+
if (!c) return t("moveElementAwayFromCollision", e.DEBUG, `Doing reverse collision on ${i.i} up to [${s.x},${s.y}].`), S(n, i, void 0, s.y, a, o);
|
|
132
|
+
if (l) return S(n, i, void 0, r.y + 1, a, o);
|
|
133
|
+
}
|
|
134
|
+
return i.y + 1 == null ? n : S(n, i, void 0, i.y + 1, a, o);
|
|
135
|
+
};
|
|
136
|
+
//#endregion
|
|
137
|
+
export { r as byId, n as clamp, p as clampX, m as collides, y as compact, x as compactItem, f as containerHeight, g as getAllCollisions, s as getCellSize, c as getCellStyle, i as getColWidth, a as getColWidth_, d as getExtent, h as getFirstCollision, o as getRowHeight, v as getStatics, S as moveElement, C as moveElementAwayFromCollision, _ as sortLayoutItems, l as toGridCoordinates, u as toGridCoordinates2 };
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport { LEVELS, log } from './logs'\nimport { type DimensionsType, type Extent, type GridLayoutById, type GridMetrics, type LayoutItemType, type PointType } from './types'\n\nexport function clamp (num: number, lowerBound: number, upperBound: number): number {\n return Math.max(Math.min(num, upperBound), lowerBound)\n}\n\n/**\n * Function to transform an array of layout items\n * into a dictionary of layout items (using the item id as the key)\n */\nexport const byId = (layout: LayoutItemType[]): GridLayoutById => {\n return layout.reduce<GridLayoutById>((acc, item) => {\n const { i } = item\n acc[i] = item\n return acc\n }, {})\n}\n\nexport const getColWidth = (params: GridMetrics): number => {\n const {\n width,\n cols,\n paddingX\n } = params\n return (width - 2 * paddingX) / cols\n}\n\nexport const getColWidth_ = (params: GridMetrics): number => {\n const {\n width,\n cols,\n marginX,\n paddingX\n } = params\n return marginX + (width - 2 * paddingX - marginX * (cols - 1)) / cols\n}\n\nexport const getRowHeight = (params: GridMetrics): number => {\n const {\n rowHeight,\n marginY,\n } = params\n return rowHeight + marginY\n}\n\nexport const getCellSize = (params: GridMetrics, cell: DimensionsType): DimensionsType => {\n const { w, h } = cell\n const {\n width,\n rowHeight,\n cols,\n marginX,\n marginY,\n paddingX\n } = params\n const colWidth = (width - 2 * paddingX - marginX * (cols - 1)) / cols\n return {\n w: w * colWidth + (w - 1) * marginX,\n h: h * rowHeight + (h - 1) * marginY\n }\n}\n\nexport const getCellStyle = (params: GridMetrics, cell: LayoutItemType, size: DimensionsType): CSSProperties => {\n const { x, y } = cell\n const {\n paddingX,\n paddingY,\n } = params\n const colWidth = getColWidth_(params)\n const rowHeight = getRowHeight(params)\n const { w, h } = size\n return {\n position: 'absolute',\n width: `${w}px`,\n height: `${h}px`,\n transform: `translate(${paddingX + x * colWidth}px, ${paddingY + y * (rowHeight)}px)`\n }\n}\n\nexport const toGridCoordinates = (params: GridMetrics, coordinates: PointType, size: DimensionsType): PointType => {\n const point = { x: 0, y: 0 }\n const { w, h } = size\n const {\n paddingX,\n paddingY,\n div\n } = params\n if (div) {\n const colWidth = getColWidth(params)\n const rowHeight = getRowHeight(params)\n const { x, y } = div.getBoundingClientRect()\n point.x = Math.ceil((coordinates.x - (x + paddingX) - 0.5 * colWidth * w) / colWidth)\n point.y = Math.ceil((coordinates.y - (y + paddingY) - 0.5 * rowHeight * h) / rowHeight)\n }\n return point\n}\n\nexport const toGridCoordinates2 = (params: GridMetrics, delta: PointType, item: LayoutItemType): PointType => {\n const point = { x: 0, y: 0 }\n const colWidth = getColWidth_(params)\n const rowHeight = getRowHeight(params)\n point.x = Math.ceil((item.x * colWidth - 0.5 * colWidth + delta.x) / colWidth)\n point.y = Math.ceil((item.y * rowHeight - 0.5 * rowHeight + delta.y) / rowHeight)\n return point\n}\n\nexport const getExtent = (layout: LayoutItemType[]): Extent => {\n return layout.reduce<Extent>(\n (acc, item) => {\n const { x, y, w, h } = item\n acc.xMax = Math.max(acc.xMax, x + w)\n acc.yMax = Math.max(acc.yMax, y + h)\n return acc\n },\n {\n xMax: 0,\n yMax: 0\n }\n )\n}\n\nexport const containerHeight = (params: { paddingY: number, marginY: number, rowHeight: number, yMax: number, minHeight: number }): number => {\n const { paddingY, marginY, rowHeight, yMax, minHeight } = params\n return Math.max(minHeight, yMax * rowHeight + marginY * (yMax - 1) + 2 * paddingY)\n}\n\nexport const clampX = (x: number, item: LayoutItemType, metrics: GridMetrics): number => {\n const { cols } = metrics\n const { w } = item\n return x + w < cols ? x : cols - w\n}\n\n/**\n * Given two layoutitems, check if they collide.\n */\nexport function collides (l1: LayoutItemType, l2: LayoutItemType): boolean {\n if (l1.i === l2.i) return false // same element\n if (l1.x + l1.w <= l2.x) return false // l1 is left of l2\n if (l1.x >= l2.x + l2.w) return false // l1 is right of l2\n if (l1.y + l1.h <= l2.y) return false // l1 is above l2\n if (l1.y >= l2.y + l2.h) return false // l1 is below l2\n return true // boxes overlap\n}\n\n/**\n * Returns the first item this layout collides with.\n * It doesn't appear to matter which order we approach this from, although\n * perhaps that is the wrong thing to do.\n *\n * @param {Object} layoutItem Layout item.\n * @return {Object|undefined} A colliding layout item, or undefined.\n */\nexport function getFirstCollision (layout: LayoutItemType[], layoutItem: LayoutItemType): LayoutItemType | undefined {\n for (let i = 0, len = layout.length; i < len; i++) {\n if (collides(layout[i], layoutItem)) return layout[i]\n }\n}\n\nexport function getAllCollisions (layout: LayoutItemType[], layoutItem: LayoutItemType): LayoutItemType[] {\n return layout.filter(l => collides(l, layoutItem))\n}\n\n/**\n * Sort layout items by column ascending then row ascending.\n * @return {Array} Array of layout objects.\n * @return {Array} Layout, sorted static items first.\n */\nexport function sortLayoutItems (layout: LayoutItemType[]): LayoutItemType[] {\n return layout.slice(0).sort(function (a, b) {\n if (a.x > b.x || (a.x === b.x && a.y > b.y)) {\n return 1\n }\n return -1\n })\n}\n\n/**\n * Get all static elements.\n */\nexport function getStatics (layout: LayoutItemType[]) {\n return layout.filter(l => l.static)\n}\n\n/**\n * Given a layout, compact it. This involves going down each y coordinate and removing gaps\n * between items.\n * Creates a new layout array.\n */\nexport function compact (layout: LayoutItemType[]): LayoutItemType[] {\n log('compact', LEVELS.INFO, layout)\n // Statics go in the compareWith array right away so items flow around them.\n const compareWith = getStatics(layout)\n // We go through the items by row and column.\n const sorted = sortLayoutItems(layout)\n // Holding for new items.\n const out = Array(layout.length)\n\n for (let i = 0, len = sorted.length; i < len; i++) {\n let l = { ...sorted[i] }\n\n // Don't move static elements\n if (!l.static) {\n l = compactItem(compareWith, l, sorted)\n\n // Add to comparison array. We only collide with items before this one.\n // Statics are already in this array.\n compareWith.push(l)\n }\n\n // Add to output array to make sure they still come out in the right order.\n out[layout.indexOf(sorted[i])] = l\n\n // Clear moved flag, if it exists.\n l.moved = false\n }\n\n return out\n}\n\n/**\n * Before moving item down, it will check if the movement will cause collisions and move those items down before.\n */\nfunction resolveCompactionCollision (layout: LayoutItemType[], item: LayoutItemType, moveToCoord: number) {\n item.y += 1\n const itemIndex = layout.findIndex(l => l.i === item.i)\n\n // Go through each item we collide with.\n for (let i = itemIndex + 1, len = layout.length; i < len; i++) {\n const otherItem = layout[i]\n // Ignore static items\n if (otherItem.static) {\n continue\n }\n\n // Optimization: we can break early if we know we're past this el\n // We can do this b/c it's a sorted layout\n if (otherItem.y > item.y + item.h) {\n break\n }\n\n if (collides(item, otherItem)) {\n resolveCompactionCollision(\n layout,\n otherItem,\n moveToCoord + item.h\n )\n }\n }\n item.y = moveToCoord\n}\n\n/**\n * Compact an item in the layout.\n * Modifies item.\n */\nexport function compactItem (compareWith: LayoutItemType[], l: LayoutItemType, fullLayout: LayoutItemType[]) {\n // Bottom 'y' possible is the bottom of the layout.\n // This allows you to do nice stuff like specify {y: Infinity}\n // This is here because the layout must be sorted in order to get the correct bottom `y`.\n l.y = Math.min(getExtent(compareWith).yMax, l.y)\n // Move the element up as far as it can go without colliding.\n while (l.y > 0 && !getFirstCollision(compareWith, l)) {\n l.y--\n }\n\n // Move it down, and keep moving it down if it's colliding.\n let collides\n // Checking the compactType null value to avoid breaking the layout when overlapping is allowed.\n while ((collides = getFirstCollision(compareWith, l))) {\n resolveCompactionCollision(fullLayout, l, collides.y + collides.h)\n }\n\n // Ensure that there are no negative positions\n l.y = Math.max(l.y, 0)\n l.x = Math.max(l.x, 0)\n\n return l\n}\n\n/**\n * Move an element. Responsible for doing cascading movements of other elements.\n *\n * Modifies layout items.\n *\n * @param {Array} layout Full layout to modify.\n * @param {LayoutItem} l element to move.\n * @param {Number} [x] X position in grid units.\n * @param {Number} [y] Y position in grid units.\n */\nexport const moveElement = (\n layout: LayoutItemType[],\n l: LayoutItemType,\n x: number | undefined,\n y: number | undefined,\n isUserAction: boolean,\n preventCollision: boolean | undefined\n): LayoutItemType[] => {\n // If this is static and not explicitly enabled as draggable,\n // no move is possible, so we can short-circuit this immediately.\n if (l.static && l.isDraggable !== true) return layout\n\n // Short-circuit if nothing to do.\n if (l.y === y && l.x === x) return layout\n\n log(\n 'moveElement',\n LEVELS.DEBUG,\n `Moving element \"${l.i}\"@[${l.x},${l.y}] => [${x},${y}]`\n )\n const oldX = l.x\n const oldY = l.y\n\n // This is quite a bit faster than extending the object\n if (typeof x === 'number') l.x = x\n if (typeof y === 'number') l.y = y\n l.moved = true\n\n // If this collides with anything, move it.\n // When doing this comparison, we have to sort the items we compare with\n // to ensure, in the case of multiple collisions, that we're getting the\n // nearest collision.\n let sorted = sortLayoutItems(layout)\n const movingUp = typeof y === 'number'\n ? oldY >= y\n : false\n // $FlowIgnore acceptable modification of read-only array as it was recently cloned\n if (movingUp) sorted = sorted.reverse()\n const collisions = getAllCollisions(sorted, l)\n const hasCollisions = collisions.length > 0\n\n // We may have collisions. We can short-circuit if we've turned off collisions or\n // allowed overlap.\n if (hasCollisions && preventCollision) {\n // If we are preventing collision but not allowing overlap, we need to\n // revert the position of this element so it goes to where it came from, rather\n // than the user's desired location.\n log(\n 'moveElement',\n LEVELS.DEBUG,\n `Collision prevented on ${l.i}, reverting.`\n )\n l.x = oldX\n l.y = oldY\n l.moved = false\n return layout // did not change so don't clone\n }\n\n // Move each item that collides away from this element.\n for (let i = 0, len = collisions.length; i < len; i++) {\n const collision = collisions[i]\n log(\n 'moveElement',\n LEVELS.DEBUG,\n `Resolving collision between \"${l.i}\"@[${l.x},${l.y}] and \"${collision.i}\"@[${collision.x},${collision.y}]`\n )\n\n // Short circuit so we can't infinite loop\n if (collision.moved) {\n continue\n }\n\n // Don't move static items - we have to move *this* element away\n if (collision.static) {\n layout = moveElementAwayFromCollision(\n layout,\n collision,\n l,\n isUserAction\n )\n } else {\n layout = moveElementAwayFromCollision(\n layout,\n l,\n collision,\n isUserAction\n )\n }\n }\n\n return layout\n}\n\n/**\n * This is where the magic needs to happen - given a collision, move an element away from the collision.\n * We attempt to move it up if there's room, otherwise it goes below.\n *\n * @param {Array} layout Full layout to modify.\n * @param {LayoutItem} collidesWith Layout item we're colliding with.\n * @param {LayoutItem} itemToMove Layout item we're moving.\n */\nexport const moveElementAwayFromCollision = (\n layout: LayoutItemType[],\n collidesWith: LayoutItemType,\n itemToMove: LayoutItemType,\n isUserAction: boolean\n) => {\n const preventCollision = collidesWith.static // we're already colliding (not for static items)\n\n // If there is enough space above the collision to put this element, move it there.\n // We only do this on the main collision as this can get funky in cascades and cause\n // unwanted swapping behavior.\n if (isUserAction) {\n // Reset isUserAction flag because we're not in the main collision anymore.\n isUserAction = false\n\n // Make a mock item so we don't modify the item here, only modify in moveElement.\n const fakeItem = {\n x: itemToMove.x,\n y: Math.max(collidesWith.y - itemToMove.h, 0),\n w: itemToMove.w,\n h: itemToMove.h,\n i: '-1'\n }\n\n const firstCollision = getFirstCollision(layout, fakeItem)\n const collisionNorth =\n firstCollision && firstCollision.y + firstCollision.h > collidesWith.y\n\n // No collision? If so, we can go up there; otherwise, we'll end up moving down as normal\n if (!firstCollision) {\n log(\n 'moveElementAwayFromCollision',\n LEVELS.DEBUG,\n `Doing reverse collision on ${itemToMove.i} up to [${fakeItem.x},${fakeItem.y}].`\n )\n return moveElement(\n layout,\n itemToMove,\n undefined,\n fakeItem.y,\n isUserAction,\n preventCollision\n )\n } else if (collisionNorth) {\n return moveElement(\n layout,\n itemToMove,\n undefined,\n collidesWith.y + 1,\n isUserAction,\n preventCollision\n )\n }\n }\n\n const newX = undefined\n const newY = itemToMove.y + 1\n\n if (newX == null && newY == null) {\n return layout\n }\n return moveElement(\n layout,\n itemToMove,\n undefined,\n itemToMove.y + 1,\n isUserAction,\n preventCollision\n )\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ulgaal/react-grid-layout",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A library to provide a grid layout system with on-the-fly adjustement in response to native HTML5 mouse and drag-and-drop events",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"table",
|
|
8
|
+
"grid",
|
|
9
|
+
"datagrid",
|
|
10
|
+
"reducer",
|
|
11
|
+
"useReducer"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://gitlab.com/coder-tribe-group/react-infra",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://gitlab.com/coder-tribe-group/react-infra/-/incidents"
|
|
16
|
+
},
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"author": {
|
|
19
|
+
"name": "Ulrich Gaal",
|
|
20
|
+
"email": "react-grid-layout@coder-tribe.ovh"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"module": "dist/index.js",
|
|
24
|
+
"types": "dist/index.d.ts",
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"lib": "tsc --p ./tsconfig.app.json && vite build --config vite.config-lib.ts",
|
|
30
|
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
31
|
+
"docs": "api-extractor --debug run ; api-documenter markdown"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": "^16.x || ^17.x || ^18.x || ^19.x",
|
|
37
|
+
"react-dom": "16.x || ^17.x || ^18.x || ^19.x",
|
|
38
|
+
"@types/react": "^18.x || ^19.x",
|
|
39
|
+
"@types/react-dom": "^18.x || ^19.x"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@eslint/js": "^9.38.0",
|
|
43
|
+
"@microsoft/api-documenter": "^7.30.6",
|
|
44
|
+
"@microsoft/api-extractor": "^7.58.8",
|
|
45
|
+
"@types/lodash": "^4.17.24",
|
|
46
|
+
"@types/react": "^18.3.12",
|
|
47
|
+
"@types/react-dom": "^18.3.1",
|
|
48
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
49
|
+
"@vitest/ui": "^4.1.8",
|
|
50
|
+
"eslint": "^9.38.0",
|
|
51
|
+
"eslint-plugin-react": "^7.37.5",
|
|
52
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
53
|
+
"eslint-plugin-react-refresh": "^0.5.2",
|
|
54
|
+
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
55
|
+
"glob": "^13.0.6",
|
|
56
|
+
"globals": "^17.6.0",
|
|
57
|
+
"jsdom": "^29.1.1",
|
|
58
|
+
"neostandard": "^0.13.0",
|
|
59
|
+
"react": "^18.3.1",
|
|
60
|
+
"react-dom": "^18.3.1",
|
|
61
|
+
"typescript": "~5.9.3",
|
|
62
|
+
"typescript-eslint": "^8.59.4",
|
|
63
|
+
"vite": "^8.0.16",
|
|
64
|
+
"vite-plugin-checker": "^0.14.1",
|
|
65
|
+
"vite-plugin-dts": "^5.0.2",
|
|
66
|
+
"vitest": "^4.1.8"
|
|
67
|
+
}
|
|
68
|
+
}
|