@deadragdoll/reactnu 0.1.73 → 0.1.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DragDrop/NuDragDropProvider.d.ts +24 -17
- package/dist/components/IconGrid/NuIconGrid.d.ts +9 -5
- package/dist/components/ListBox/ListBox.d.ts +6 -4
- package/dist/components/ListBox/internals/ListBoxGroupView.d.ts +3 -2
- package/dist/components/ListBox/internals/ListBoxItemView.d.ts +3 -2
- package/dist/components/ListView/ListView.d.ts +13 -2
- package/dist/components/ListView/internals/ListViewRow.d.ts +6 -1
- package/dist/components/TreeListView/TreeListView.d.ts +8 -4
- package/dist/components/TreeListView/internals/TreeListViewRow.d.ts +3 -2
- package/dist/index.cjs +393 -382
- package/dist/index.js +653 -636
- package/docs/API_REFERENCE.md +4 -1
- package/docs/GETTING_STARTED.md +1 -1
- package/docs/IconGrid.md +4 -4
- package/docs/ListBox.md +3 -0
- package/docs/ListView.md +10 -0
- package/docs/NuDragDropProvider.md +39 -6
- package/docs/TreeListView.md +8 -0
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -1061,226 +1061,167 @@ var import_react6 = require("react");
|
|
|
1061
1061
|
|
|
1062
1062
|
// src/components/DragDrop/NuDragDropProvider.tsx
|
|
1063
1063
|
var import_react5 = require("react");
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
function getThemePortalStyle(anchor) {
|
|
1067
|
-
if (typeof window === "undefined") {
|
|
1068
|
-
return void 0;
|
|
1069
|
-
}
|
|
1070
|
-
const themeRoot = anchor?.closest(".nu-theme-root");
|
|
1071
|
-
if (!themeRoot) {
|
|
1072
|
-
return void 0;
|
|
1073
|
-
}
|
|
1074
|
-
const computed = window.getComputedStyle(themeRoot);
|
|
1075
|
-
const style = {
|
|
1076
|
-
color: computed.color,
|
|
1077
|
-
fontFamily: computed.fontFamily,
|
|
1078
|
-
fontSize: computed.fontSize
|
|
1079
|
-
};
|
|
1080
|
-
for (const propertyName of computed) {
|
|
1081
|
-
if (propertyName.startsWith("--nu-")) {
|
|
1082
|
-
style[propertyName] = computed.getPropertyValue(propertyName).trim();
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
return style;
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
// src/components/DragDrop/NuDragDropProvider.tsx
|
|
1064
|
+
var import_react_dnd = require("react-dnd");
|
|
1065
|
+
var import_react_dnd_html5_backend = require("react-dnd-html5-backend");
|
|
1089
1066
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1090
|
-
var
|
|
1091
|
-
function
|
|
1092
|
-
const rect = sourceElement.getBoundingClientRect();
|
|
1093
|
-
const preview = sourceElement.cloneNode(true);
|
|
1094
|
-
preview.removeAttribute("id");
|
|
1095
|
-
preview.setAttribute("aria-hidden", "true");
|
|
1096
|
-
Object.assign(preview.style, {
|
|
1097
|
-
height: `${rect.height}px`,
|
|
1098
|
-
left: `${rect.left}px`,
|
|
1099
|
-
margin: "0",
|
|
1100
|
-
opacity: "0.85",
|
|
1101
|
-
pointerEvents: "none",
|
|
1102
|
-
position: "fixed",
|
|
1103
|
-
top: `${rect.top}px`,
|
|
1104
|
-
width: `${rect.width}px`,
|
|
1105
|
-
zIndex: "2147483647"
|
|
1106
|
-
});
|
|
1107
|
-
const themeStyle = getThemePortalStyle(sourceElement);
|
|
1108
|
-
Object.entries(themeStyle ?? {}).forEach(([property, value]) => {
|
|
1109
|
-
if (value !== void 0) {
|
|
1110
|
-
preview.style.setProperty(property, String(value));
|
|
1111
|
-
}
|
|
1112
|
-
});
|
|
1113
|
-
document.body.append(preview);
|
|
1114
|
-
return preview;
|
|
1115
|
-
}
|
|
1116
|
-
function createController() {
|
|
1117
|
-
const targets = /* @__PURE__ */ new Map();
|
|
1118
|
-
let activeDrag = null;
|
|
1119
|
-
function findTarget(clientX, clientY) {
|
|
1120
|
-
const elementAtPoint = document.elementFromPoint(clientX, clientY);
|
|
1121
|
-
let candidate = elementAtPoint;
|
|
1122
|
-
while (candidate) {
|
|
1123
|
-
const target = targets.get(candidate);
|
|
1124
|
-
if (target) {
|
|
1125
|
-
return target;
|
|
1126
|
-
}
|
|
1127
|
-
candidate = candidate.parentElement;
|
|
1128
|
-
}
|
|
1129
|
-
return Array.from(targets.values()).reverse().find((target) => {
|
|
1130
|
-
const rect = target.element.getBoundingClientRect();
|
|
1131
|
-
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
1132
|
-
});
|
|
1133
|
-
}
|
|
1134
|
-
function clearActiveDrag() {
|
|
1135
|
-
activeDrag?.preview.remove();
|
|
1136
|
-
activeDrag = null;
|
|
1137
|
-
}
|
|
1067
|
+
var NU_DRAG_ITEM_TYPE = "reactnu-shared-item";
|
|
1068
|
+
function getDropContext(item, element, type, clientOffset) {
|
|
1138
1069
|
return {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
sourceElement,
|
|
1145
|
-
sourceType
|
|
1146
|
-
};
|
|
1147
|
-
},
|
|
1148
|
-
cancelDrag: clearActiveDrag,
|
|
1149
|
-
dropAt(clientX, clientY) {
|
|
1150
|
-
const currentDrag = activeDrag;
|
|
1151
|
-
if (!currentDrag) {
|
|
1152
|
-
return false;
|
|
1153
|
-
}
|
|
1154
|
-
const target = findTarget(clientX, clientY);
|
|
1155
|
-
clearActiveDrag();
|
|
1156
|
-
if (!target || target.element === currentDrag.sourceElement) {
|
|
1157
|
-
return false;
|
|
1158
|
-
}
|
|
1159
|
-
if (target.accepts?.(currentDrag.item) === false) {
|
|
1160
|
-
return false;
|
|
1161
|
-
}
|
|
1162
|
-
return target.onDrop(currentDrag.item, {
|
|
1163
|
-
clientX,
|
|
1164
|
-
clientY,
|
|
1165
|
-
source: {
|
|
1166
|
-
element: currentDrag.sourceElement,
|
|
1167
|
-
type: currentDrag.sourceType
|
|
1168
|
-
},
|
|
1169
|
-
target: { element: target.element, type: target.type }
|
|
1170
|
-
}) !== false;
|
|
1171
|
-
},
|
|
1172
|
-
moveDrag(clientX, clientY) {
|
|
1173
|
-
const currentDrag = activeDrag;
|
|
1174
|
-
if (!currentDrag) {
|
|
1175
|
-
return;
|
|
1176
|
-
}
|
|
1177
|
-
const rect = currentDrag.sourceElement.getBoundingClientRect();
|
|
1178
|
-
currentDrag.preview.style.left = `${Math.round(clientX - rect.width / 2)}px`;
|
|
1179
|
-
currentDrag.preview.style.top = `${Math.round(clientY - rect.height / 2)}px`;
|
|
1070
|
+
clientX: clientOffset?.x ?? 0,
|
|
1071
|
+
clientY: clientOffset?.y ?? 0,
|
|
1072
|
+
source: {
|
|
1073
|
+
element: item.sourceElement ?? element,
|
|
1074
|
+
type: item.sourceType
|
|
1180
1075
|
},
|
|
1181
|
-
|
|
1182
|
-
targets.set(element, { ...options, element });
|
|
1183
|
-
return () => targets.delete(element);
|
|
1184
|
-
}
|
|
1076
|
+
target: { element, type }
|
|
1185
1077
|
};
|
|
1186
1078
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1079
|
+
function NuDragPreviewLayer() {
|
|
1080
|
+
const { isDragging, item, offset } = (0, import_react_dnd.useDragLayer)((monitor) => ({
|
|
1081
|
+
isDragging: monitor.isDragging(),
|
|
1082
|
+
item: monitor.getItem() ?? null,
|
|
1083
|
+
offset: monitor.getClientOffset()
|
|
1084
|
+
}));
|
|
1085
|
+
if (!isDragging || !item?.preview || !offset) {
|
|
1086
|
+
return null;
|
|
1087
|
+
}
|
|
1088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1089
|
+
"div",
|
|
1090
|
+
{
|
|
1091
|
+
"aria-hidden": "true",
|
|
1092
|
+
style: {
|
|
1093
|
+
left: 0,
|
|
1094
|
+
pointerEvents: "none",
|
|
1095
|
+
position: "fixed",
|
|
1096
|
+
top: 0,
|
|
1097
|
+
transform: `translate(${Math.round(offset.x + 12)}px, ${Math.round(offset.y + 12)}px)`,
|
|
1098
|
+
zIndex: 2147483647
|
|
1099
|
+
},
|
|
1100
|
+
children: item.preview
|
|
1101
|
+
}
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1189
1104
|
function NuDragDropProvider({ children }) {
|
|
1190
|
-
const
|
|
1191
|
-
|
|
1105
|
+
const { dragDropManager } = (0, import_react5.useContext)(import_react_dnd.DndContext);
|
|
1106
|
+
if (dragDropManager) {
|
|
1107
|
+
return children;
|
|
1108
|
+
}
|
|
1109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_dnd.DndProvider, { backend: import_react_dnd_html5_backend.HTML5Backend, children: [
|
|
1110
|
+
children,
|
|
1111
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NuDragPreviewLayer, {})
|
|
1112
|
+
] });
|
|
1192
1113
|
}
|
|
1193
1114
|
function useNuDragDrop() {
|
|
1194
|
-
return (0,
|
|
1115
|
+
return (0, import_react_dnd.useDragDropManager)();
|
|
1195
1116
|
}
|
|
1196
1117
|
function useNuDropTarget(element, options) {
|
|
1197
|
-
const
|
|
1118
|
+
const [{ canDrop, isOver, item }, drop] = (0, import_react_dnd.useDrop)(
|
|
1119
|
+
() => ({
|
|
1120
|
+
accept: NU_DRAG_ITEM_TYPE,
|
|
1121
|
+
canDrop: (dragItem) => options ? options.accepts?.(dragItem) !== false : false,
|
|
1122
|
+
collect: (monitor) => ({
|
|
1123
|
+
canDrop: monitor.canDrop(),
|
|
1124
|
+
isOver: monitor.isOver({ shallow: true }),
|
|
1125
|
+
item: monitor.isOver({ shallow: true }) ? monitor.getItem() ?? null : null
|
|
1126
|
+
}),
|
|
1127
|
+
drop: (dragItem, monitor) => {
|
|
1128
|
+
if (!options || monitor.didDrop()) {
|
|
1129
|
+
return void 0;
|
|
1130
|
+
}
|
|
1131
|
+
const result = options.onDrop(
|
|
1132
|
+
dragItem,
|
|
1133
|
+
getDropContext(
|
|
1134
|
+
dragItem,
|
|
1135
|
+
element ?? dragItem.sourceElement ?? document.body,
|
|
1136
|
+
options.type,
|
|
1137
|
+
monitor.getClientOffset()
|
|
1138
|
+
)
|
|
1139
|
+
);
|
|
1140
|
+
if (result === false) {
|
|
1141
|
+
return { accepted: false };
|
|
1142
|
+
}
|
|
1143
|
+
return {
|
|
1144
|
+
...typeof result === "object" && result ? result : {},
|
|
1145
|
+
accepted: true
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
}),
|
|
1149
|
+
[element, options]
|
|
1150
|
+
);
|
|
1198
1151
|
(0, import_react5.useEffect)(() => {
|
|
1199
1152
|
if (!element || !options) {
|
|
1153
|
+
drop(null);
|
|
1200
1154
|
return void 0;
|
|
1201
1155
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1156
|
+
drop(element);
|
|
1157
|
+
return () => {
|
|
1158
|
+
drop(null);
|
|
1159
|
+
};
|
|
1160
|
+
}, [drop, element, options]);
|
|
1161
|
+
const previousItemRef = (0, import_react5.useRef)(null);
|
|
1162
|
+
(0, import_react5.useEffect)(() => {
|
|
1163
|
+
const previousItem = previousItemRef.current;
|
|
1164
|
+
if (isOver && item && (!previousItem || previousItem !== item)) {
|
|
1165
|
+
options?.onDragEnter?.(item, canDrop);
|
|
1166
|
+
} else if (!isOver && previousItem) {
|
|
1167
|
+
options?.onDragLeave?.(previousItem);
|
|
1168
|
+
}
|
|
1169
|
+
previousItemRef.current = isOver ? item : null;
|
|
1170
|
+
}, [canDrop, isOver, item, options]);
|
|
1171
|
+
return { canDrop, isOver, item };
|
|
1204
1172
|
}
|
|
1205
1173
|
function useNuDragSource({
|
|
1206
1174
|
disabled = false,
|
|
1207
1175
|
getItem,
|
|
1208
1176
|
onDropAccepted,
|
|
1177
|
+
renderPreview,
|
|
1209
1178
|
sourceType
|
|
1210
1179
|
}) {
|
|
1211
|
-
const
|
|
1212
|
-
const
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
startY: 0
|
|
1218
|
-
});
|
|
1219
|
-
const state = stateRef.current;
|
|
1220
|
-
function stop(event, shouldDrop) {
|
|
1221
|
-
if (state.pointerId !== event.pointerId) {
|
|
1222
|
-
return;
|
|
1223
|
-
}
|
|
1224
|
-
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
1225
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
1226
|
-
}
|
|
1227
|
-
state.pointerId = -1;
|
|
1228
|
-
if (state.dragging && shouldDrop && controller.dropAt(event.clientX, event.clientY)) {
|
|
1229
|
-
onDropAccepted?.();
|
|
1230
|
-
} else if (state.dragging) {
|
|
1231
|
-
controller.cancelDrag();
|
|
1232
|
-
}
|
|
1233
|
-
state.dragging = false;
|
|
1234
|
-
state.sourceElement = null;
|
|
1235
|
-
}
|
|
1236
|
-
return {
|
|
1237
|
-
onPointerCancel(event) {
|
|
1238
|
-
stop(event, false);
|
|
1239
|
-
},
|
|
1240
|
-
onPointerDown(event) {
|
|
1241
|
-
if (disabled || event.button !== 0) {
|
|
1242
|
-
return;
|
|
1243
|
-
}
|
|
1244
|
-
if (event.target instanceof HTMLElement && event.target.closest("button, input, select, textarea, a")) {
|
|
1245
|
-
return;
|
|
1246
|
-
}
|
|
1247
|
-
state.dragging = false;
|
|
1248
|
-
state.pointerId = event.pointerId;
|
|
1249
|
-
state.sourceElement = event.currentTarget;
|
|
1250
|
-
state.startX = event.clientX;
|
|
1251
|
-
state.startY = event.clientY;
|
|
1252
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
1253
|
-
},
|
|
1254
|
-
onPointerMove(event) {
|
|
1255
|
-
if (state.pointerId !== event.pointerId || !state.sourceElement) {
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
if (!state.dragging) {
|
|
1259
|
-
const distance = Math.max(
|
|
1260
|
-
Math.abs(event.clientX - state.startX),
|
|
1261
|
-
Math.abs(event.clientY - state.startY)
|
|
1262
|
-
);
|
|
1263
|
-
if (distance < DRAG_THRESHOLD) {
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1180
|
+
const sourceElementRef = (0, import_react5.useRef)(null);
|
|
1181
|
+
const [{ isDragging }, drag, preview] = (0, import_react_dnd.useDrag)(
|
|
1182
|
+
() => ({
|
|
1183
|
+
type: NU_DRAG_ITEM_TYPE,
|
|
1184
|
+
canDrag: () => !disabled && Boolean(getItem()),
|
|
1185
|
+
item: () => {
|
|
1266
1186
|
const item = getItem();
|
|
1267
1187
|
if (!item) {
|
|
1268
|
-
|
|
1269
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
1270
|
-
}
|
|
1271
|
-
state.pointerId = -1;
|
|
1272
|
-
state.sourceElement = null;
|
|
1273
|
-
return;
|
|
1188
|
+
throw new Error("getItem must return a drag item when dragging is enabled.");
|
|
1274
1189
|
}
|
|
1275
|
-
|
|
1276
|
-
|
|
1190
|
+
return {
|
|
1191
|
+
...item,
|
|
1192
|
+
preview: renderPreview?.(item),
|
|
1193
|
+
sourceElement: sourceElementRef.current,
|
|
1194
|
+
sourceType
|
|
1195
|
+
};
|
|
1196
|
+
},
|
|
1197
|
+
end: (_item, monitor) => {
|
|
1198
|
+
const result = monitor.getDropResult();
|
|
1199
|
+
if (monitor.didDrop() && result?.accepted !== false) {
|
|
1200
|
+
onDropAccepted?.(result ?? {});
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1203
|
+
collect: (monitor) => ({ isDragging: monitor.isDragging() })
|
|
1204
|
+
}),
|
|
1205
|
+
[disabled, getItem, onDropAccepted, renderPreview, sourceType]
|
|
1206
|
+
);
|
|
1207
|
+
const dragRef = (0, import_react5.useCallback)(
|
|
1208
|
+
(element) => {
|
|
1209
|
+
if (disabled) {
|
|
1210
|
+
sourceElementRef.current = null;
|
|
1211
|
+
drag(null);
|
|
1212
|
+
return;
|
|
1277
1213
|
}
|
|
1278
|
-
|
|
1214
|
+
sourceElementRef.current = element;
|
|
1215
|
+
drag(element);
|
|
1279
1216
|
},
|
|
1280
|
-
|
|
1281
|
-
|
|
1217
|
+
[disabled, drag]
|
|
1218
|
+
);
|
|
1219
|
+
(0, import_react5.useEffect)(() => {
|
|
1220
|
+
if (renderPreview) {
|
|
1221
|
+
preview((0, import_react_dnd_html5_backend.getEmptyImage)(), { captureDraggingState: true });
|
|
1282
1222
|
}
|
|
1283
|
-
};
|
|
1223
|
+
}, [preview, renderPreview]);
|
|
1224
|
+
return { dragRef, isDragging };
|
|
1284
1225
|
}
|
|
1285
1226
|
|
|
1286
1227
|
// src/components/ListBox/internals/ListBoxCheckControl.tsx
|
|
@@ -1331,6 +1272,7 @@ function ListBoxItemViewInner({
|
|
|
1331
1272
|
onDoubleClick,
|
|
1332
1273
|
onDragOut,
|
|
1333
1274
|
onToggleCheck,
|
|
1275
|
+
renderDragPreview,
|
|
1334
1276
|
registerItemRef,
|
|
1335
1277
|
rightCheckBox,
|
|
1336
1278
|
uncheckedShape
|
|
@@ -1339,6 +1281,7 @@ function ListBoxItemViewInner({
|
|
|
1339
1281
|
disabled: item.disabled || !getDragItem,
|
|
1340
1282
|
getItem: () => getDragItem?.(item, group) ?? false,
|
|
1341
1283
|
onDropAccepted: () => onDragOut?.(item, group),
|
|
1284
|
+
renderPreview: renderDragPreview ? () => renderDragPreview(item, group) : void 0,
|
|
1342
1285
|
sourceType: "listbox-item"
|
|
1343
1286
|
});
|
|
1344
1287
|
function handleActivate() {
|
|
@@ -1386,11 +1329,10 @@ function ListBoxItemViewInner({
|
|
|
1386
1329
|
onClick: handleActivate,
|
|
1387
1330
|
onContextMenu: onPopupMenu ? handleContextMenu : void 0,
|
|
1388
1331
|
onDoubleClick: handleDoubleClick,
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
ref: (node) => registerItemRef(itemId, node),
|
|
1332
|
+
ref: (node) => {
|
|
1333
|
+
registerItemRef(itemId, node);
|
|
1334
|
+
dragSource.dragRef(node);
|
|
1335
|
+
},
|
|
1394
1336
|
role: "option",
|
|
1395
1337
|
children: [
|
|
1396
1338
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "nu-listbox__item-main", children: [
|
|
@@ -1416,6 +1358,7 @@ function ListBoxGroupView({
|
|
|
1416
1358
|
onActivateItem,
|
|
1417
1359
|
onDoubleClickItem,
|
|
1418
1360
|
onItemDragOut,
|
|
1361
|
+
renderDragPreview,
|
|
1419
1362
|
onPopupMenuItem,
|
|
1420
1363
|
onToggleItemCheck,
|
|
1421
1364
|
registerItemRef,
|
|
@@ -1450,6 +1393,7 @@ function ListBoxGroupView({
|
|
|
1450
1393
|
onActivate: onActivateItem,
|
|
1451
1394
|
onDoubleClick: onDoubleClickItem,
|
|
1452
1395
|
onDragOut: onItemDragOut,
|
|
1396
|
+
renderDragPreview,
|
|
1453
1397
|
onPopupMenu: onPopupMenuItem,
|
|
1454
1398
|
onToggleCheck: onToggleItemCheck,
|
|
1455
1399
|
registerItemRef,
|
|
@@ -1477,6 +1421,7 @@ function ListBoxInner({
|
|
|
1477
1421
|
onItemDragOut,
|
|
1478
1422
|
onItemSelect,
|
|
1479
1423
|
onDrop,
|
|
1424
|
+
renderDragPreview,
|
|
1480
1425
|
rightCheckBox = false,
|
|
1481
1426
|
selectedId,
|
|
1482
1427
|
uncheckedShape = "box",
|
|
@@ -1679,6 +1624,7 @@ function ListBoxInner({
|
|
|
1679
1624
|
onItemDragOut,
|
|
1680
1625
|
onPopupMenuItem: handleItemPopupMenu,
|
|
1681
1626
|
onToggleItemCheck: toggleItemCheck,
|
|
1627
|
+
renderDragPreview,
|
|
1682
1628
|
registerItemRef,
|
|
1683
1629
|
resolvedActiveId,
|
|
1684
1630
|
rightCheckBox,
|
|
@@ -1690,7 +1636,10 @@ function ListBoxInner({
|
|
|
1690
1636
|
}
|
|
1691
1637
|
);
|
|
1692
1638
|
}
|
|
1693
|
-
|
|
1639
|
+
function ListBoxWithDragDrop(props, ref) {
|
|
1640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NuDragDropProvider, { children: ListBoxInner(props, ref) });
|
|
1641
|
+
}
|
|
1642
|
+
var ListBox = (0, import_react7.forwardRef)(ListBoxWithDragDrop);
|
|
1694
1643
|
|
|
1695
1644
|
// src/components/Stack/Stack.tsx
|
|
1696
1645
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
@@ -4724,6 +4673,31 @@ var import_react27 = require("react");
|
|
|
4724
4673
|
// src/components/PopupMenu/PopupMenu.tsx
|
|
4725
4674
|
var import_react24 = require("react");
|
|
4726
4675
|
var import_react_dom2 = require("react-dom");
|
|
4676
|
+
|
|
4677
|
+
// src/components/_shared/themePortal.ts
|
|
4678
|
+
function getThemePortalStyle(anchor) {
|
|
4679
|
+
if (typeof window === "undefined") {
|
|
4680
|
+
return void 0;
|
|
4681
|
+
}
|
|
4682
|
+
const themeRoot = anchor?.closest(".nu-theme-root");
|
|
4683
|
+
if (!themeRoot) {
|
|
4684
|
+
return void 0;
|
|
4685
|
+
}
|
|
4686
|
+
const computed = window.getComputedStyle(themeRoot);
|
|
4687
|
+
const style = {
|
|
4688
|
+
color: computed.color,
|
|
4689
|
+
fontFamily: computed.fontFamily,
|
|
4690
|
+
fontSize: computed.fontSize
|
|
4691
|
+
};
|
|
4692
|
+
for (const propertyName of computed) {
|
|
4693
|
+
if (propertyName.startsWith("--nu-")) {
|
|
4694
|
+
style[propertyName] = computed.getPropertyValue(propertyName).trim();
|
|
4695
|
+
}
|
|
4696
|
+
}
|
|
4697
|
+
return style;
|
|
4698
|
+
}
|
|
4699
|
+
|
|
4700
|
+
// src/components/PopupMenu/PopupMenu.tsx
|
|
4727
4701
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4728
4702
|
function hasVisibleChildren2(item) {
|
|
4729
4703
|
return Boolean(
|
|
@@ -4956,7 +4930,6 @@ function useNuIconGridContext() {
|
|
|
4956
4930
|
|
|
4957
4931
|
// src/components/IconGrid/NuIconGrid.tsx
|
|
4958
4932
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
4959
|
-
var DRAG_THRESHOLD2 = 3;
|
|
4960
4933
|
var gridRegistrations = /* @__PURE__ */ new Map();
|
|
4961
4934
|
function clamp2(value, minimum, maximum) {
|
|
4962
4935
|
return Math.min(Math.max(value, minimum), maximum);
|
|
@@ -4967,23 +4940,6 @@ function resolveIconContextMenuItems(source, icon) {
|
|
|
4967
4940
|
function resolveGridContextMenuItems(source, manager) {
|
|
4968
4941
|
return typeof source === "function" ? source(manager) : source ?? [];
|
|
4969
4942
|
}
|
|
4970
|
-
function findGridRegistrationAtPoint(clientX, clientY) {
|
|
4971
|
-
const target = document.elementFromPoint(clientX, clientY);
|
|
4972
|
-
const gridElement = target?.closest(".nu-icon-grid");
|
|
4973
|
-
if (gridElement) {
|
|
4974
|
-
return gridRegistrations.get(gridElement);
|
|
4975
|
-
}
|
|
4976
|
-
if (target?.closest(".nu-window")) {
|
|
4977
|
-
return void 0;
|
|
4978
|
-
}
|
|
4979
|
-
return Array.from(gridRegistrations.values()).reverse().find((registration) => {
|
|
4980
|
-
if (!registration.dropTarget) {
|
|
4981
|
-
return false;
|
|
4982
|
-
}
|
|
4983
|
-
const rect = registration.element.getBoundingClientRect();
|
|
4984
|
-
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
4985
|
-
});
|
|
4986
|
-
}
|
|
4987
4943
|
function getTransferredPosition(targetGrid, iconElement, clientX, clientY) {
|
|
4988
4944
|
const targetRect = targetGrid.getBoundingClientRect();
|
|
4989
4945
|
const iconRect = iconElement.getBoundingClientRect();
|
|
@@ -5005,149 +4961,31 @@ function getTransferredPosition(targetGrid, iconElement, clientX, clientY) {
|
|
|
5005
4961
|
};
|
|
5006
4962
|
}
|
|
5007
4963
|
function NuIconGridItem({
|
|
5008
|
-
gridElement,
|
|
5009
4964
|
icon,
|
|
5010
|
-
onDragOut
|
|
5011
|
-
onIconMoveOut
|
|
4965
|
+
onDragOut
|
|
5012
4966
|
}) {
|
|
5013
4967
|
const manager = useNuIconGridContext();
|
|
5014
|
-
const dragDrop = useNuDragDrop();
|
|
5015
4968
|
const contextMenu = usePopupMenu();
|
|
5016
|
-
const dragStartRef = (0, import_react27.useRef)(void 0);
|
|
5017
|
-
const isDraggingRef = (0, import_react27.useRef)(false);
|
|
5018
|
-
const [isDragging, setIsDragging] = (0, import_react27.useState)(false);
|
|
5019
|
-
const suppressClickRef = (0, import_react27.useRef)(false);
|
|
5020
|
-
const latestPositionRef = (0, import_react27.useRef)(icon.position);
|
|
5021
4969
|
const contextMenuItems = resolveIconContextMenuItems(
|
|
5022
4970
|
icon.contextMenuItems,
|
|
5023
4971
|
icon
|
|
5024
4972
|
);
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
latestPositionRef.current = icon.position;
|
|
5031
|
-
isDraggingRef.current = false;
|
|
5032
|
-
dragStartRef.current = {
|
|
5033
|
-
clientX: event.clientX,
|
|
5034
|
-
clientY: event.clientY,
|
|
5035
|
-
pointerId: event.pointerId,
|
|
5036
|
-
position: icon.position
|
|
5037
|
-
};
|
|
5038
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
5039
|
-
}
|
|
5040
|
-
function handlePointerMove(event) {
|
|
5041
|
-
const dragStart = dragStartRef.current;
|
|
5042
|
-
if (!dragStart || dragStart.pointerId !== event.pointerId || !gridElement) {
|
|
5043
|
-
return;
|
|
5044
|
-
}
|
|
5045
|
-
const deltaX = event.clientX - dragStart.clientX;
|
|
5046
|
-
const deltaY = event.clientY - dragStart.clientY;
|
|
5047
|
-
if (!isDraggingRef.current && Math.max(Math.abs(deltaX), Math.abs(deltaY)) < DRAG_THRESHOLD2) {
|
|
5048
|
-
return;
|
|
5049
|
-
}
|
|
5050
|
-
if (!isDraggingRef.current) {
|
|
5051
|
-
isDraggingRef.current = true;
|
|
5052
|
-
setIsDragging(true);
|
|
5053
|
-
dragDrop.beginDrag(
|
|
5054
|
-
{ data: icon, id: icon.id, type: "icon" },
|
|
5055
|
-
event.currentTarget,
|
|
5056
|
-
"icon-grid"
|
|
5057
|
-
);
|
|
5058
|
-
}
|
|
5059
|
-
dragDrop.moveDrag(event.clientX, event.clientY);
|
|
5060
|
-
const gridRect = gridElement.getBoundingClientRect();
|
|
5061
|
-
const iconRect = event.currentTarget.getBoundingClientRect();
|
|
5062
|
-
const position = {
|
|
5063
|
-
x: Math.round(
|
|
5064
|
-
clamp2(
|
|
5065
|
-
dragStart.position.x + deltaX,
|
|
5066
|
-
0,
|
|
5067
|
-
Math.max(0, gridRect.width - iconRect.width)
|
|
5068
|
-
)
|
|
5069
|
-
),
|
|
5070
|
-
y: Math.round(
|
|
5071
|
-
clamp2(
|
|
5072
|
-
dragStart.position.y + deltaY,
|
|
5073
|
-
0,
|
|
5074
|
-
Math.max(0, gridRect.height - iconRect.height)
|
|
5075
|
-
)
|
|
5076
|
-
)
|
|
5077
|
-
};
|
|
5078
|
-
latestPositionRef.current = position;
|
|
5079
|
-
}
|
|
5080
|
-
function finishDragging(event) {
|
|
5081
|
-
const dragStart = dragStartRef.current;
|
|
5082
|
-
if (!dragStart || dragStart.pointerId !== event.pointerId) {
|
|
5083
|
-
return;
|
|
5084
|
-
}
|
|
5085
|
-
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
5086
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
5087
|
-
}
|
|
5088
|
-
dragStartRef.current = void 0;
|
|
5089
|
-
if (!isDraggingRef.current) {
|
|
5090
|
-
return;
|
|
5091
|
-
}
|
|
5092
|
-
suppressClickRef.current = true;
|
|
5093
|
-
isDraggingRef.current = false;
|
|
5094
|
-
setIsDragging(false);
|
|
5095
|
-
if (event.type === "pointercancel" || !gridElement) {
|
|
5096
|
-
dragDrop.cancelDrag();
|
|
5097
|
-
return;
|
|
5098
|
-
}
|
|
5099
|
-
if (dragDrop.dropAt(event.clientX, event.clientY)) {
|
|
5100
|
-
manager.removeIcon(icon.id);
|
|
5101
|
-
onDragOut?.({ data: icon, id: icon.id, type: "icon" });
|
|
5102
|
-
return;
|
|
5103
|
-
}
|
|
5104
|
-
const targetRegistration = findGridRegistrationAtPoint(
|
|
5105
|
-
event.clientX,
|
|
5106
|
-
event.clientY
|
|
5107
|
-
);
|
|
5108
|
-
if (!targetRegistration) {
|
|
5109
|
-
return;
|
|
5110
|
-
}
|
|
5111
|
-
if (targetRegistration.element === gridElement) {
|
|
5112
|
-
manager.moveIcon(icon.id, latestPositionRef.current);
|
|
5113
|
-
icon.onPositionChange?.(latestPositionRef.current, {
|
|
5114
|
-
...icon,
|
|
5115
|
-
position: latestPositionRef.current
|
|
5116
|
-
});
|
|
5117
|
-
return;
|
|
5118
|
-
}
|
|
5119
|
-
if (!targetRegistration.manager.icons.some(
|
|
5120
|
-
(targetIcon) => targetIcon.id === icon.id
|
|
5121
|
-
)) {
|
|
5122
|
-
const position = getTransferredPosition(
|
|
5123
|
-
targetRegistration.element,
|
|
5124
|
-
event.currentTarget,
|
|
5125
|
-
event.clientX,
|
|
5126
|
-
event.clientY
|
|
5127
|
-
);
|
|
5128
|
-
const transferredIcon = { ...icon, position };
|
|
5129
|
-
const context = {
|
|
5130
|
-
position,
|
|
5131
|
-
source: manager,
|
|
5132
|
-
sourceGrid: gridElement,
|
|
5133
|
-
target: targetRegistration.manager,
|
|
5134
|
-
targetGrid: targetRegistration.element
|
|
5135
|
-
};
|
|
5136
|
-
if (targetRegistration.accepts?.(transferredIcon) !== false && targetRegistration.onIconDrop?.(transferredIcon, context) !== false) {
|
|
5137
|
-
targetRegistration.manager.addIcon(transferredIcon);
|
|
5138
|
-
targetRegistration.manager.selectIcon(transferredIcon.id);
|
|
5139
|
-
manager.removeIcon(icon.id);
|
|
5140
|
-
onIconMoveOut?.(transferredIcon, context);
|
|
4973
|
+
const dragSource = useNuDragSource({
|
|
4974
|
+
disabled: icon.disabled,
|
|
4975
|
+
getItem: () => ({ data: icon, id: icon.id, type: "icon" }),
|
|
4976
|
+
onDropAccepted: (result) => {
|
|
4977
|
+
if (result.targetType === "icon-grid") {
|
|
5141
4978
|
return;
|
|
5142
4979
|
}
|
|
5143
|
-
|
|
5144
|
-
|
|
4980
|
+
const dragItem = { data: icon, id: icon.id, type: "icon" };
|
|
4981
|
+
const shouldMove = result.action !== "copy" && onDragOut?.(dragItem, result) !== false;
|
|
4982
|
+
if (shouldMove) {
|
|
4983
|
+
manager.removeIcon(icon.id);
|
|
4984
|
+
}
|
|
4985
|
+
},
|
|
4986
|
+
sourceType: "icon-grid"
|
|
4987
|
+
});
|
|
5145
4988
|
function handleClick(event) {
|
|
5146
|
-
if (suppressClickRef.current) {
|
|
5147
|
-
suppressClickRef.current = false;
|
|
5148
|
-
event.preventDefault();
|
|
5149
|
-
return;
|
|
5150
|
-
}
|
|
5151
4989
|
manager.selectIcon(icon.id);
|
|
5152
4990
|
icon.onClick?.(event);
|
|
5153
4991
|
}
|
|
@@ -5175,17 +5013,14 @@ function NuIconGridItem({
|
|
|
5175
5013
|
{
|
|
5176
5014
|
"aria-haspopup": contextMenuItems.length > 0 ? "menu" : void 0,
|
|
5177
5015
|
className: "nu-icon-grid__icon",
|
|
5178
|
-
"data-dragging": isDragging || void 0,
|
|
5016
|
+
"data-dragging": dragSource.isDragging || void 0,
|
|
5179
5017
|
"data-selected": manager.selectedIconId === icon.id || void 0,
|
|
5180
5018
|
disabled: icon.disabled,
|
|
5181
5019
|
onClick: handleClick,
|
|
5182
5020
|
onContextMenu: handleContextMenu,
|
|
5183
5021
|
onDoubleClick: icon.onDoubleClick,
|
|
5184
5022
|
onKeyDown: handleKeyDown,
|
|
5185
|
-
|
|
5186
|
-
onPointerMove: handlePointerMove,
|
|
5187
|
-
onPointerUp: finishDragging,
|
|
5188
|
-
onPointerCancel: finishDragging,
|
|
5023
|
+
ref: dragSource.dragRef,
|
|
5189
5024
|
style: { left: icon.position.x, top: icon.position.y },
|
|
5190
5025
|
type: "button",
|
|
5191
5026
|
children: [
|
|
@@ -5205,7 +5040,7 @@ function NuIconGridItem({
|
|
|
5205
5040
|
)
|
|
5206
5041
|
] });
|
|
5207
5042
|
}
|
|
5208
|
-
function
|
|
5043
|
+
function NuIconGridContent({
|
|
5209
5044
|
accepts,
|
|
5210
5045
|
acceptsDrop,
|
|
5211
5046
|
className,
|
|
@@ -5230,15 +5065,89 @@ function NuIconGrid({
|
|
|
5230
5065
|
() => resolveGridContextMenuItems(contextMenuItemsSource, manager),
|
|
5231
5066
|
[contextMenuItemsSource, manager]
|
|
5232
5067
|
);
|
|
5233
|
-
const sharedDropTargetOptions = (0, import_react27.useMemo)(
|
|
5234
|
-
()
|
|
5235
|
-
|
|
5236
|
-
|
|
5068
|
+
const sharedDropTargetOptions = (0, import_react27.useMemo)(() => {
|
|
5069
|
+
if (!gridElement) {
|
|
5070
|
+
return void 0;
|
|
5071
|
+
}
|
|
5072
|
+
return {
|
|
5073
|
+
accepts: (item) => {
|
|
5074
|
+
if (item.type === "icon") {
|
|
5075
|
+
return accepts?.(item.data) !== false;
|
|
5076
|
+
}
|
|
5077
|
+
return Boolean(onDrop) && acceptsDrop?.(item) !== false;
|
|
5078
|
+
},
|
|
5079
|
+
onDrop: (item, context) => {
|
|
5080
|
+
if (item.type !== "icon") {
|
|
5081
|
+
return onDrop?.(item, context) ?? false;
|
|
5082
|
+
}
|
|
5083
|
+
const sourceGridElement = context.source.element.closest(
|
|
5084
|
+
".nu-icon-grid"
|
|
5085
|
+
);
|
|
5086
|
+
const sourceRegistration = sourceGridElement ? gridRegistrations.get(sourceGridElement) : void 0;
|
|
5087
|
+
if (!sourceRegistration) {
|
|
5088
|
+
return false;
|
|
5089
|
+
}
|
|
5090
|
+
const sourceIcon = item.data;
|
|
5091
|
+
const position = getTransferredPosition(
|
|
5092
|
+
gridElement,
|
|
5093
|
+
context.source.element,
|
|
5094
|
+
context.clientX,
|
|
5095
|
+
context.clientY
|
|
5096
|
+
);
|
|
5097
|
+
if (sourceRegistration.element === gridElement) {
|
|
5098
|
+
manager.moveIcon(sourceIcon.id, position);
|
|
5099
|
+
sourceIcon.onPositionChange?.(position, {
|
|
5100
|
+
...sourceIcon,
|
|
5101
|
+
position
|
|
5102
|
+
});
|
|
5103
|
+
return { action: "move", targetType: "icon-grid" };
|
|
5104
|
+
}
|
|
5105
|
+
if (manager.icons.some((targetIcon) => targetIcon.id === sourceIcon.id)) {
|
|
5106
|
+
return false;
|
|
5107
|
+
}
|
|
5108
|
+
const transferredIcon = { ...sourceIcon, position };
|
|
5109
|
+
const dropContext = {
|
|
5110
|
+
position,
|
|
5111
|
+
source: sourceRegistration.manager,
|
|
5112
|
+
sourceGrid: sourceRegistration.element,
|
|
5113
|
+
target: manager,
|
|
5114
|
+
targetGrid: gridElement
|
|
5115
|
+
};
|
|
5116
|
+
if (onIconDrop?.(transferredIcon, dropContext) === false) {
|
|
5117
|
+
return false;
|
|
5118
|
+
}
|
|
5119
|
+
manager.addIcon(transferredIcon);
|
|
5120
|
+
manager.selectIcon(transferredIcon.id);
|
|
5121
|
+
sourceRegistration.manager.removeIcon(sourceIcon.id);
|
|
5122
|
+
sourceRegistration.onIconMoveOut?.(transferredIcon, dropContext);
|
|
5123
|
+
return { action: "move", targetType: "icon-grid" };
|
|
5124
|
+
},
|
|
5237
5125
|
type: "icon-grid"
|
|
5238
|
-
}
|
|
5239
|
-
|
|
5240
|
-
);
|
|
5126
|
+
};
|
|
5127
|
+
}, [accepts, acceptsDrop, gridElement, manager, onDrop, onIconDrop]);
|
|
5241
5128
|
useNuDropTarget(gridElement, sharedDropTargetOptions);
|
|
5129
|
+
const backgroundDropTargetOptions = (0, import_react27.useMemo)(() => {
|
|
5130
|
+
if (!dropTarget || !gridElement || !sharedDropTargetOptions) {
|
|
5131
|
+
return void 0;
|
|
5132
|
+
}
|
|
5133
|
+
return {
|
|
5134
|
+
...sharedDropTargetOptions,
|
|
5135
|
+
onDrop: (item, context) => {
|
|
5136
|
+
const rect = gridElement.getBoundingClientRect();
|
|
5137
|
+
if (context.clientX < rect.left || context.clientX > rect.right || context.clientY < rect.top || context.clientY > rect.bottom) {
|
|
5138
|
+
return false;
|
|
5139
|
+
}
|
|
5140
|
+
return sharedDropTargetOptions.onDrop(item, {
|
|
5141
|
+
...context,
|
|
5142
|
+
target: { element: gridElement, type: "icon-grid" }
|
|
5143
|
+
});
|
|
5144
|
+
}
|
|
5145
|
+
};
|
|
5146
|
+
}, [dropTarget, gridElement, sharedDropTargetOptions]);
|
|
5147
|
+
useNuDropTarget(
|
|
5148
|
+
dropTarget && typeof document !== "undefined" ? document.body : null,
|
|
5149
|
+
backgroundDropTargetOptions
|
|
5150
|
+
);
|
|
5242
5151
|
(0, import_react27.useLayoutEffect)(() => {
|
|
5243
5152
|
if (!gridElement) {
|
|
5244
5153
|
return;
|
|
@@ -5265,16 +5174,15 @@ function NuIconGrid({
|
|
|
5265
5174
|
return;
|
|
5266
5175
|
}
|
|
5267
5176
|
gridRegistrations.set(gridElement, {
|
|
5268
|
-
accepts,
|
|
5269
|
-
dropTarget,
|
|
5270
5177
|
element: gridElement,
|
|
5271
5178
|
manager,
|
|
5272
|
-
onIconDrop
|
|
5179
|
+
onIconDrop,
|
|
5180
|
+
onIconMoveOut
|
|
5273
5181
|
});
|
|
5274
5182
|
return () => {
|
|
5275
5183
|
gridRegistrations.delete(gridElement);
|
|
5276
5184
|
};
|
|
5277
|
-
}, [
|
|
5185
|
+
}, [gridElement, manager, onIconDrop, onIconMoveOut]);
|
|
5278
5186
|
function handleContextMenu(event) {
|
|
5279
5187
|
onContextMenu?.(event);
|
|
5280
5188
|
if (event.defaultPrevented || contextMenuItems.length === 0) {
|
|
@@ -5290,6 +5198,7 @@ function NuIconGrid({
|
|
|
5290
5198
|
...props,
|
|
5291
5199
|
"aria-label": props["aria-label"] ?? "Application icons",
|
|
5292
5200
|
className: ["nu-icon-grid", className].filter(Boolean).join(" "),
|
|
5201
|
+
"data-drop-target": dropTarget || void 0,
|
|
5293
5202
|
onContextMenu: handleContextMenu,
|
|
5294
5203
|
onPointerDown: (event) => {
|
|
5295
5204
|
onPointerDown?.(event);
|
|
@@ -5306,10 +5215,8 @@ function NuIconGrid({
|
|
|
5306
5215
|
manager.icons.map((icon) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
5307
5216
|
NuIconGridItem,
|
|
5308
5217
|
{
|
|
5309
|
-
gridElement,
|
|
5310
5218
|
icon,
|
|
5311
|
-
onDragOut
|
|
5312
|
-
onIconMoveOut
|
|
5219
|
+
onDragOut
|
|
5313
5220
|
},
|
|
5314
5221
|
icon.id
|
|
5315
5222
|
)),
|
|
@@ -5326,6 +5233,9 @@ function NuIconGrid({
|
|
|
5326
5233
|
}
|
|
5327
5234
|
);
|
|
5328
5235
|
}
|
|
5236
|
+
function NuIconGrid(props) {
|
|
5237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(NuDragDropProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(NuIconGridContent, { ...props }) });
|
|
5238
|
+
}
|
|
5329
5239
|
|
|
5330
5240
|
// src/components/IconGrid/NuIconProvider.tsx
|
|
5331
5241
|
var import_react28 = require("react");
|
|
@@ -6212,16 +6122,26 @@ function ListViewRowInner({
|
|
|
6212
6122
|
isActive,
|
|
6213
6123
|
isChecked,
|
|
6214
6124
|
isSelected,
|
|
6125
|
+
getDragItem,
|
|
6215
6126
|
onActivate,
|
|
6216
6127
|
onDoubleClick,
|
|
6128
|
+
onDragOut,
|
|
6217
6129
|
onToggleCheck,
|
|
6218
6130
|
registerRowRef,
|
|
6131
|
+
renderDragPreview,
|
|
6219
6132
|
row,
|
|
6220
6133
|
showCheckBox,
|
|
6221
6134
|
templateColumns,
|
|
6222
6135
|
uncheckedShape
|
|
6223
6136
|
}) {
|
|
6224
6137
|
const rowId = row.id;
|
|
6138
|
+
const dragSource = useNuDragSource({
|
|
6139
|
+
disabled: row.disabled || !getDragItem,
|
|
6140
|
+
getItem: () => getDragItem?.(row) ?? false,
|
|
6141
|
+
onDropAccepted: () => onDragOut?.(row),
|
|
6142
|
+
renderPreview: renderDragPreview ? () => renderDragPreview(row) : void 0,
|
|
6143
|
+
sourceType: "list-view-row"
|
|
6144
|
+
});
|
|
6225
6145
|
function handleActivate() {
|
|
6226
6146
|
if (!row.disabled) {
|
|
6227
6147
|
onActivate(rowId);
|
|
@@ -6252,7 +6172,10 @@ function ListViewRowInner({
|
|
|
6252
6172
|
id: rowId,
|
|
6253
6173
|
onClick: handleActivate,
|
|
6254
6174
|
onDoubleClick: handleDoubleClick,
|
|
6255
|
-
ref: (node) =>
|
|
6175
|
+
ref: (node) => {
|
|
6176
|
+
registerRowRef(rowId, node);
|
|
6177
|
+
dragSource.dragRef(node);
|
|
6178
|
+
},
|
|
6256
6179
|
role: "row",
|
|
6257
6180
|
style: {
|
|
6258
6181
|
"--nu-list-view-columns": templateColumns
|
|
@@ -6289,6 +6212,7 @@ var ListViewRow = (0, import_react32.memo)(ListViewRowInner);
|
|
|
6289
6212
|
// src/components/ListView/ListView.tsx
|
|
6290
6213
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
6291
6214
|
function ListViewInner({
|
|
6215
|
+
acceptsDrop,
|
|
6292
6216
|
activeRowId: activeRowIdProp,
|
|
6293
6217
|
checkedIds,
|
|
6294
6218
|
className,
|
|
@@ -6296,16 +6220,21 @@ function ListViewInner({
|
|
|
6296
6220
|
data,
|
|
6297
6221
|
defaultActiveRowId,
|
|
6298
6222
|
emptyText = "No rows",
|
|
6223
|
+
getDragItem,
|
|
6299
6224
|
onActiveRowChange,
|
|
6300
6225
|
onRowCheckChange,
|
|
6301
6226
|
onRowDoubleClick,
|
|
6227
|
+
onRowDragOut,
|
|
6302
6228
|
onRowSelect,
|
|
6229
|
+
onDrop,
|
|
6230
|
+
renderDragPreview,
|
|
6303
6231
|
selectedId,
|
|
6304
6232
|
showCheckBox = false,
|
|
6305
6233
|
uncheckedShape = "box",
|
|
6306
6234
|
...props
|
|
6307
6235
|
}, ref) {
|
|
6308
6236
|
const rootRef = (0, import_react33.useRef)(null);
|
|
6237
|
+
const [rootElement, setRootElement] = (0, import_react33.useState)(null);
|
|
6309
6238
|
const rowRefs = (0, import_react33.useRef)({});
|
|
6310
6239
|
const selectableRows = (0, import_react33.useMemo)(
|
|
6311
6240
|
() => data.filter((row) => !row.disabled),
|
|
@@ -6324,6 +6253,15 @@ function ListViewInner({
|
|
|
6324
6253
|
);
|
|
6325
6254
|
return [checkboxColumn, ...dataColumns].filter(Boolean).join(" ");
|
|
6326
6255
|
}, [columns, showCheckBox]);
|
|
6256
|
+
const dropTargetOptions = (0, import_react33.useMemo)(
|
|
6257
|
+
() => onDrop ? { accepts: acceptsDrop, onDrop, type: "list-view" } : void 0,
|
|
6258
|
+
[acceptsDrop, onDrop]
|
|
6259
|
+
);
|
|
6260
|
+
useNuDropTarget(rootElement, dropTargetOptions);
|
|
6261
|
+
const setRootRef = (0, import_react33.useCallback)((node) => {
|
|
6262
|
+
rootRef.current = node;
|
|
6263
|
+
setRootElement(node);
|
|
6264
|
+
}, []);
|
|
6327
6265
|
(0, import_react33.useEffect)(() => {
|
|
6328
6266
|
if (!resolvedActiveRowId) {
|
|
6329
6267
|
return;
|
|
@@ -6462,7 +6400,7 @@ function ListViewInner({
|
|
|
6462
6400
|
"aria-activedescendant": resolvedActiveRowId ?? void 0,
|
|
6463
6401
|
className: ["nu-list-view", className].filter(Boolean).join(" "),
|
|
6464
6402
|
onKeyDown: handleKeyDown,
|
|
6465
|
-
ref:
|
|
6403
|
+
ref: setRootRef,
|
|
6466
6404
|
role: "grid",
|
|
6467
6405
|
tabIndex: 0,
|
|
6468
6406
|
children: [
|
|
@@ -6496,13 +6434,16 @@ function ListViewInner({
|
|
|
6496
6434
|
ListViewRow,
|
|
6497
6435
|
{
|
|
6498
6436
|
columns,
|
|
6437
|
+
getDragItem,
|
|
6499
6438
|
isActive: row.id === resolvedActiveRowId,
|
|
6500
6439
|
isChecked: isRowChecked(row),
|
|
6501
6440
|
isSelected: row.id === selectedId,
|
|
6502
6441
|
onActivate: activateRowId,
|
|
6503
6442
|
onDoubleClick: onRowDoubleClick,
|
|
6443
|
+
onDragOut: onRowDragOut,
|
|
6504
6444
|
onToggleCheck: toggleRowCheck,
|
|
6505
6445
|
registerRowRef,
|
|
6446
|
+
renderDragPreview,
|
|
6506
6447
|
row,
|
|
6507
6448
|
showCheckBox,
|
|
6508
6449
|
templateColumns,
|
|
@@ -6514,7 +6455,10 @@ function ListViewInner({
|
|
|
6514
6455
|
}
|
|
6515
6456
|
);
|
|
6516
6457
|
}
|
|
6517
|
-
|
|
6458
|
+
function ListViewWithDragDrop(props, ref) {
|
|
6459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(NuDragDropProvider, { children: ListViewInner(props, ref) });
|
|
6460
|
+
}
|
|
6461
|
+
var ListView = (0, import_react33.forwardRef)(ListViewWithDragDrop);
|
|
6518
6462
|
|
|
6519
6463
|
// src/components/MaskedField/MaskedField.tsx
|
|
6520
6464
|
var import_react34 = require("react");
|
|
@@ -9522,6 +9466,7 @@ function TreeListViewRowInner({
|
|
|
9522
9466
|
onActivateItem,
|
|
9523
9467
|
onDoubleClickItem,
|
|
9524
9468
|
onItemDragOut,
|
|
9469
|
+
renderDragPreview,
|
|
9525
9470
|
onPopupMenuItem,
|
|
9526
9471
|
onToggleItemCheck,
|
|
9527
9472
|
onToggleItemExpanded,
|
|
@@ -9553,6 +9498,7 @@ function TreeListViewRowInner({
|
|
|
9553
9498
|
disabled: item.disabled || !getDragItem,
|
|
9554
9499
|
getItem: () => getDragItem?.(item, dragContext) ?? false,
|
|
9555
9500
|
onDropAccepted: () => onItemDragOut?.(item, dragContext),
|
|
9501
|
+
renderPreview: renderDragPreview ? () => renderDragPreview(item, dragContext) : void 0,
|
|
9556
9502
|
sourceType: "tree-list-item"
|
|
9557
9503
|
});
|
|
9558
9504
|
function handleActivate() {
|
|
@@ -9619,11 +9565,10 @@ function TreeListViewRowInner({
|
|
|
9619
9565
|
onClick: handleActivate,
|
|
9620
9566
|
onContextMenu: onPopupMenuItem ? handleContextMenu : void 0,
|
|
9621
9567
|
onDoubleClick: handleDoubleClick,
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
ref: (node) => registerItemRef(itemId, node),
|
|
9568
|
+
ref: (node) => {
|
|
9569
|
+
registerItemRef(itemId, node);
|
|
9570
|
+
dragSource.dragRef(node);
|
|
9571
|
+
},
|
|
9627
9572
|
role: "row",
|
|
9628
9573
|
style: {
|
|
9629
9574
|
"--nu-tree-list-view-columns": templateColumns
|
|
@@ -9803,11 +9748,42 @@ var TreeListViewRow = (0, import_react46.memo)(
|
|
|
9803
9748
|
|
|
9804
9749
|
// src/components/TreeListView/TreeListView.tsx
|
|
9805
9750
|
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
9751
|
+
function getColumnStorageKey(columnStoreKey) {
|
|
9752
|
+
const normalizedKey = columnStoreKey?.trim();
|
|
9753
|
+
return normalizedKey ? `reactnu.${normalizedKey}` : null;
|
|
9754
|
+
}
|
|
9755
|
+
function readStoredColumnWidths(storageKey, columns) {
|
|
9756
|
+
if (!storageKey || typeof window === "undefined") {
|
|
9757
|
+
return {};
|
|
9758
|
+
}
|
|
9759
|
+
try {
|
|
9760
|
+
const rawValue = window.localStorage.getItem(storageKey);
|
|
9761
|
+
if (!rawValue) {
|
|
9762
|
+
return {};
|
|
9763
|
+
}
|
|
9764
|
+
const parsedValue = JSON.parse(rawValue);
|
|
9765
|
+
if (!parsedValue || typeof parsedValue !== "object") {
|
|
9766
|
+
return {};
|
|
9767
|
+
}
|
|
9768
|
+
return Object.fromEntries(
|
|
9769
|
+
columns.flatMap((column) => {
|
|
9770
|
+
const width = parsedValue[column.id];
|
|
9771
|
+
if (typeof width !== "number" || !Number.isFinite(width)) {
|
|
9772
|
+
return [];
|
|
9773
|
+
}
|
|
9774
|
+
return [[column.id, Math.max(width, column.minWidth ?? 0)]];
|
|
9775
|
+
})
|
|
9776
|
+
);
|
|
9777
|
+
} catch {
|
|
9778
|
+
return {};
|
|
9779
|
+
}
|
|
9780
|
+
}
|
|
9806
9781
|
function TreeListViewInner({
|
|
9807
9782
|
acceptsDrop,
|
|
9808
9783
|
activeItemId: activeItemIdProp,
|
|
9809
9784
|
checkedIds,
|
|
9810
9785
|
className,
|
|
9786
|
+
columnStoreKey,
|
|
9811
9787
|
columns,
|
|
9812
9788
|
onPopupMenu,
|
|
9813
9789
|
data,
|
|
@@ -9823,6 +9799,7 @@ function TreeListViewInner({
|
|
|
9823
9799
|
onItemCheckChange,
|
|
9824
9800
|
onItemDoubleClick,
|
|
9825
9801
|
onItemDragOut,
|
|
9802
|
+
renderDragPreview,
|
|
9826
9803
|
onItemSelect,
|
|
9827
9804
|
onDrop,
|
|
9828
9805
|
selectedId,
|
|
@@ -9832,6 +9809,9 @@ function TreeListViewInner({
|
|
|
9832
9809
|
const rootRef = (0, import_react47.useRef)(null);
|
|
9833
9810
|
const [rootElement, setRootElement] = (0, import_react47.useState)(null);
|
|
9834
9811
|
const treeId = (0, import_react47.useId)();
|
|
9812
|
+
const storageKey = getColumnStorageKey(columnStoreKey);
|
|
9813
|
+
const loadedStorageKeyRef = (0, import_react47.useRef)(storageKey);
|
|
9814
|
+
const shouldPersistColumnWidthsRef = (0, import_react47.useRef)(false);
|
|
9835
9815
|
const itemRefs = (0, import_react47.useRef)({});
|
|
9836
9816
|
const resizeFrameRef = (0, import_react47.useRef)(null);
|
|
9837
9817
|
const resizeStateRef = (0, import_react47.useRef)(null);
|
|
@@ -9845,7 +9825,7 @@ function TreeListViewInner({
|
|
|
9845
9825
|
});
|
|
9846
9826
|
const [uncontrolledSelectedId, setUncontrolledSelectedId] = (0, import_react47.useState)(null);
|
|
9847
9827
|
const [autoColumnWidths, setAutoColumnWidths] = (0, import_react47.useState)({});
|
|
9848
|
-
const [userColumnWidths, setUserColumnWidths] = (0, import_react47.useState)(
|
|
9828
|
+
const [userColumnWidths, setUserColumnWidths] = (0, import_react47.useState)(() => readStoredColumnWidths(storageKey, columns));
|
|
9849
9829
|
const isActiveControlled = activeItemIdProp !== void 0;
|
|
9850
9830
|
const resolvedExpandedIds = isExpandedControlled ? expandedIds : uncontrolledExpandedIds;
|
|
9851
9831
|
const expandedIdSet = (0, import_react47.useMemo)(
|
|
@@ -9907,6 +9887,27 @@ function TreeListViewInner({
|
|
|
9907
9887
|
block: "nearest"
|
|
9908
9888
|
});
|
|
9909
9889
|
}, [resolvedActiveItemId]);
|
|
9890
|
+
(0, import_react47.useEffect)(() => {
|
|
9891
|
+
if (loadedStorageKeyRef.current === storageKey) {
|
|
9892
|
+
return;
|
|
9893
|
+
}
|
|
9894
|
+
loadedStorageKeyRef.current = storageKey;
|
|
9895
|
+
shouldPersistColumnWidthsRef.current = false;
|
|
9896
|
+
setUserColumnWidths(readStoredColumnWidths(storageKey, columns));
|
|
9897
|
+
}, [columns, storageKey]);
|
|
9898
|
+
(0, import_react47.useEffect)(() => {
|
|
9899
|
+
if (!shouldPersistColumnWidthsRef.current) {
|
|
9900
|
+
return;
|
|
9901
|
+
}
|
|
9902
|
+
shouldPersistColumnWidthsRef.current = false;
|
|
9903
|
+
if (!storageKey || typeof window === "undefined") {
|
|
9904
|
+
return;
|
|
9905
|
+
}
|
|
9906
|
+
try {
|
|
9907
|
+
window.localStorage.setItem(storageKey, JSON.stringify(userColumnWidths));
|
|
9908
|
+
} catch {
|
|
9909
|
+
}
|
|
9910
|
+
}, [storageKey, userColumnWidths]);
|
|
9910
9911
|
const registerItemRef = (0, import_react47.useCallback)(
|
|
9911
9912
|
(itemId, node) => {
|
|
9912
9913
|
itemRefs.current[itemId] = node;
|
|
@@ -10197,9 +10198,15 @@ function TreeListViewInner({
|
|
|
10197
10198
|
return;
|
|
10198
10199
|
}
|
|
10199
10200
|
setUserColumnWidths(
|
|
10200
|
-
(currentWidths) =>
|
|
10201
|
-
|
|
10202
|
-
|
|
10201
|
+
(currentWidths) => {
|
|
10202
|
+
if (currentWidths[resizeState.columnId] === resizeState.nextWidth) {
|
|
10203
|
+
return currentWidths;
|
|
10204
|
+
}
|
|
10205
|
+
shouldPersistColumnWidthsRef.current = true;
|
|
10206
|
+
return {
|
|
10207
|
+
...currentWidths,
|
|
10208
|
+
[resizeState.columnId]: resizeState.nextWidth
|
|
10209
|
+
};
|
|
10203
10210
|
}
|
|
10204
10211
|
);
|
|
10205
10212
|
}
|
|
@@ -10311,6 +10318,7 @@ function TreeListViewInner({
|
|
|
10311
10318
|
onActivateItem: activateEntry,
|
|
10312
10319
|
onDoubleClickItem: onItemDoubleClick ? handleItemDoubleClick : void 0,
|
|
10313
10320
|
onItemDragOut,
|
|
10321
|
+
renderDragPreview,
|
|
10314
10322
|
onPopupMenuItem: handleItemPopupMenu,
|
|
10315
10323
|
onToggleItemCheck: handleItemCheckChange,
|
|
10316
10324
|
onToggleItemExpanded: setExpandedState,
|
|
@@ -10329,7 +10337,10 @@ function TreeListViewInner({
|
|
|
10329
10337
|
}
|
|
10330
10338
|
);
|
|
10331
10339
|
}
|
|
10332
|
-
|
|
10340
|
+
function TreeListViewWithDragDrop(props, ref) {
|
|
10341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(NuDragDropProvider, { children: TreeListViewInner(props, ref) });
|
|
10342
|
+
}
|
|
10343
|
+
var TreeListView = (0, import_react47.forwardRef)(TreeListViewWithDragDrop);
|
|
10333
10344
|
|
|
10334
10345
|
// src/theme/NuThemeProvider.tsx
|
|
10335
10346
|
var import_react49 = require("react");
|