@sia.soul/sia-react-ui 0.1.15 → 0.1.18
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/{chunk-MUTJVDM6.js → chunk-I3EF5SF2.js} +1 -1
- package/dist/{chunk-E7F47Z2C.js → chunk-JX53ZBIW.js} +2 -2
- package/dist/{chunk-R3TYVU53.js → chunk-LPRFOSRZ.js} +385 -7
- package/dist/{chunk-ALWHRV4L.js → chunk-SUMXP2SF.js} +10 -5
- package/dist/{chunk-25BU7YTB.js → chunk-UCQZZ2YC.js} +2 -2
- package/dist/core.cjs +442 -61
- package/dist/core.css +38 -6
- package/dist/core.js +3 -3
- package/dist/index.cjs +3274 -2461
- package/dist/index.css +38 -6
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1170 -736
- package/dist/rich-text-editor.cjs +10 -5
- package/dist/rich-text-editor.js +2 -2
- package/dist/select-date-range.cjs +400 -24
- package/dist/select-date-range.js +3 -3
- package/package.json +1 -1
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
Popover,
|
|
6
6
|
Tooltip,
|
|
7
7
|
useOverlayLifecycle
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LPRFOSRZ.js";
|
|
9
9
|
import {
|
|
10
10
|
Dropdown,
|
|
11
11
|
Icon
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-SUMXP2SF.js";
|
|
13
13
|
import {
|
|
14
14
|
Button
|
|
15
15
|
} from "./chunk-TZGUBGA4.js";
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
Icon,
|
|
4
4
|
Input,
|
|
5
5
|
PopupPortal
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SUMXP2SF.js";
|
|
7
7
|
import {
|
|
8
8
|
Button
|
|
9
9
|
} from "./chunk-TZGUBGA4.js";
|
|
@@ -780,7 +780,7 @@ function openModal(config) {
|
|
|
780
780
|
let currentOpen = true;
|
|
781
781
|
let destroyed = false;
|
|
782
782
|
let cleanupTimer;
|
|
783
|
-
function
|
|
783
|
+
function cleanup2() {
|
|
784
784
|
if (destroyed) return;
|
|
785
785
|
destroyed = true;
|
|
786
786
|
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
@@ -792,7 +792,7 @@ function openModal(config) {
|
|
|
792
792
|
if (destroyed || !currentOpen) return;
|
|
793
793
|
currentOpen = false;
|
|
794
794
|
render();
|
|
795
|
-
cleanupTimer = window.setTimeout(
|
|
795
|
+
cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
|
|
796
796
|
}
|
|
797
797
|
function render() {
|
|
798
798
|
root.render(/* @__PURE__ */ jsx3(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
@@ -1011,8 +1011,383 @@ function SelectionPanel({
|
|
|
1011
1011
|
] });
|
|
1012
1012
|
}
|
|
1013
1013
|
|
|
1014
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
1015
|
+
import { useEffect as useEffect7 } from "react";
|
|
1016
|
+
|
|
1017
|
+
// src/components/useScrollbarProximity.ts
|
|
1018
|
+
import { useEffect as useEffect6 } from "react";
|
|
1019
|
+
var users = 0;
|
|
1020
|
+
var cleanup;
|
|
1021
|
+
function useScrollbarProximity() {
|
|
1022
|
+
useEffect6(() => {
|
|
1023
|
+
if (users++ === 0) {
|
|
1024
|
+
let frame = 0;
|
|
1025
|
+
let x = -Infinity;
|
|
1026
|
+
let y = -Infinity;
|
|
1027
|
+
const nearby = /* @__PURE__ */ new Set();
|
|
1028
|
+
const clear = () => {
|
|
1029
|
+
nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
|
|
1030
|
+
nearby.clear();
|
|
1031
|
+
};
|
|
1032
|
+
const update = () => {
|
|
1033
|
+
frame = 0;
|
|
1034
|
+
const next = /* @__PURE__ */ new Set();
|
|
1035
|
+
document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
|
|
1036
|
+
const rect = track.getBoundingClientRect();
|
|
1037
|
+
const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
|
|
1038
|
+
if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
|
|
1039
|
+
next.add(track);
|
|
1040
|
+
if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
nearby.forEach((track) => {
|
|
1044
|
+
if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
|
|
1045
|
+
});
|
|
1046
|
+
nearby.clear();
|
|
1047
|
+
next.forEach((track) => nearby.add(track));
|
|
1048
|
+
};
|
|
1049
|
+
const move = (event) => {
|
|
1050
|
+
if (event.pointerType === "touch") return;
|
|
1051
|
+
x = event.clientX;
|
|
1052
|
+
y = event.clientY;
|
|
1053
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
1054
|
+
};
|
|
1055
|
+
const leave = () => {
|
|
1056
|
+
x = y = -Infinity;
|
|
1057
|
+
clear();
|
|
1058
|
+
};
|
|
1059
|
+
document.addEventListener("pointermove", move, { passive: true });
|
|
1060
|
+
document.documentElement.addEventListener("pointerleave", leave);
|
|
1061
|
+
window.addEventListener("blur", leave);
|
|
1062
|
+
cleanup = () => {
|
|
1063
|
+
if (frame) cancelAnimationFrame(frame);
|
|
1064
|
+
document.removeEventListener("pointermove", move);
|
|
1065
|
+
document.documentElement.removeEventListener("pointerleave", leave);
|
|
1066
|
+
window.removeEventListener("blur", leave);
|
|
1067
|
+
clear();
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
return () => {
|
|
1071
|
+
if (--users === 0) {
|
|
1072
|
+
cleanup?.();
|
|
1073
|
+
cleanup = void 0;
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
}, []);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
1080
|
+
var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
1081
|
+
var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
|
|
1082
|
+
function isRootScroller(target) {
|
|
1083
|
+
return target === document.scrollingElement || target === document.documentElement;
|
|
1084
|
+
}
|
|
1085
|
+
function canScroll(target, axis) {
|
|
1086
|
+
if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
|
|
1087
|
+
if (isRootScroller(target)) {
|
|
1088
|
+
return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
1089
|
+
}
|
|
1090
|
+
const style = getComputedStyle(target);
|
|
1091
|
+
const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
|
|
1092
|
+
const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
1093
|
+
return hasOverflow && scrollableOverflow.has(overflow);
|
|
1094
|
+
}
|
|
1095
|
+
function visibleRect(target) {
|
|
1096
|
+
if (isRootScroller(target)) {
|
|
1097
|
+
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
1098
|
+
}
|
|
1099
|
+
const ownRect = target.getBoundingClientRect();
|
|
1100
|
+
let top = Math.max(0, ownRect.top);
|
|
1101
|
+
let right = Math.min(window.innerWidth, ownRect.right);
|
|
1102
|
+
let bottom = Math.min(window.innerHeight, ownRect.bottom);
|
|
1103
|
+
let left = Math.max(0, ownRect.left);
|
|
1104
|
+
let parent = target.parentElement;
|
|
1105
|
+
while (parent && parent !== document.body && parent !== document.documentElement) {
|
|
1106
|
+
const style = getComputedStyle(parent);
|
|
1107
|
+
const clipX = clippingOverflow.has(style.overflowX);
|
|
1108
|
+
const clipY = clippingOverflow.has(style.overflowY);
|
|
1109
|
+
if (clipX || clipY) {
|
|
1110
|
+
const rect = parent.getBoundingClientRect();
|
|
1111
|
+
if (clipX) {
|
|
1112
|
+
left = Math.max(left, rect.left);
|
|
1113
|
+
right = Math.min(right, rect.right);
|
|
1114
|
+
}
|
|
1115
|
+
if (clipY) {
|
|
1116
|
+
top = Math.max(top, rect.top);
|
|
1117
|
+
bottom = Math.min(bottom, rect.bottom);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
parent = parent.parentElement;
|
|
1121
|
+
}
|
|
1122
|
+
return {
|
|
1123
|
+
top,
|
|
1124
|
+
right,
|
|
1125
|
+
bottom,
|
|
1126
|
+
left,
|
|
1127
|
+
width: Math.max(0, right - left),
|
|
1128
|
+
height: Math.max(0, bottom - top)
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
function createTrack(axis) {
|
|
1132
|
+
const track = document.createElement("div");
|
|
1133
|
+
const thumb = document.createElement("div");
|
|
1134
|
+
track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
|
|
1135
|
+
thumb.className = "sia-floating-scrollbar__thumb";
|
|
1136
|
+
track.dataset.axis = axis;
|
|
1137
|
+
track.setAttribute("aria-hidden", "true");
|
|
1138
|
+
track.append(thumb);
|
|
1139
|
+
return { track, thumb };
|
|
1140
|
+
}
|
|
1141
|
+
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
1142
|
+
useScrollbarProximity();
|
|
1143
|
+
useEffect7(() => {
|
|
1144
|
+
if (disabled) return;
|
|
1145
|
+
const layer = document.createElement("div");
|
|
1146
|
+
layer.className = "sia-floating-scrollbar-layer";
|
|
1147
|
+
layer.setAttribute("aria-hidden", "true");
|
|
1148
|
+
document.body.append(layer);
|
|
1149
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1150
|
+
let scanFrame = 0;
|
|
1151
|
+
let updateFrame = 0;
|
|
1152
|
+
const setEntryVisible = (entry, visible) => {
|
|
1153
|
+
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
1154
|
+
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
1155
|
+
};
|
|
1156
|
+
const showEntry = (entry) => {
|
|
1157
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1158
|
+
entry.hideTimer = null;
|
|
1159
|
+
setEntryVisible(entry, true);
|
|
1160
|
+
};
|
|
1161
|
+
const scheduleHide = (entry, delay = 500) => {
|
|
1162
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1163
|
+
entry.hideTimer = window.setTimeout(() => {
|
|
1164
|
+
entry.hideTimer = null;
|
|
1165
|
+
if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
|
|
1166
|
+
}, delay);
|
|
1167
|
+
};
|
|
1168
|
+
const updateEntry = (entry) => {
|
|
1169
|
+
const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
|
|
1170
|
+
const hasHorizontal = canScroll(target, "horizontal");
|
|
1171
|
+
const hasVertical = canScroll(target, "vertical");
|
|
1172
|
+
const rect = visibleRect(target);
|
|
1173
|
+
const thickness = 10;
|
|
1174
|
+
horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
|
|
1175
|
+
verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
|
|
1176
|
+
if (!horizontalTrack.hidden) {
|
|
1177
|
+
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
1178
|
+
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
1179
|
+
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
1180
|
+
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
1181
|
+
horizontalTrack.style.left = `${rect.left}px`;
|
|
1182
|
+
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
1183
|
+
horizontalTrack.style.width = `${trackWidth}px`;
|
|
1184
|
+
horizontalTrack.style.height = `${thickness}px`;
|
|
1185
|
+
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
1186
|
+
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
1187
|
+
}
|
|
1188
|
+
if (!verticalTrack.hidden) {
|
|
1189
|
+
const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
|
|
1190
|
+
const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
|
|
1191
|
+
const travel = Math.max(0, trackHeight - thumbHeight);
|
|
1192
|
+
const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
|
|
1193
|
+
verticalTrack.style.left = `${rect.right - thickness}px`;
|
|
1194
|
+
verticalTrack.style.top = `${rect.top}px`;
|
|
1195
|
+
verticalTrack.style.width = `${thickness}px`;
|
|
1196
|
+
verticalTrack.style.height = `${trackHeight}px`;
|
|
1197
|
+
verticalThumb.style.height = `${thumbHeight}px`;
|
|
1198
|
+
verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
const scheduleUpdateAll = () => {
|
|
1202
|
+
if (updateFrame) return;
|
|
1203
|
+
updateFrame = window.requestAnimationFrame(() => {
|
|
1204
|
+
updateFrame = 0;
|
|
1205
|
+
entries.forEach(updateEntry);
|
|
1206
|
+
});
|
|
1207
|
+
};
|
|
1208
|
+
const bindTrackDrag = (entry, axis, track, thumb) => {
|
|
1209
|
+
const target = entry.target;
|
|
1210
|
+
const onTrackPointerEnter = () => {
|
|
1211
|
+
entry.hoveringTrack = true;
|
|
1212
|
+
showEntry(entry);
|
|
1213
|
+
};
|
|
1214
|
+
const onTrackPointerLeave = () => {
|
|
1215
|
+
entry.hoveringTrack = false;
|
|
1216
|
+
scheduleHide(entry);
|
|
1217
|
+
};
|
|
1218
|
+
const onTrackPointerDown = (event) => {
|
|
1219
|
+
if (event.target === thumb || event.button !== 0) return;
|
|
1220
|
+
event.preventDefault();
|
|
1221
|
+
event.stopPropagation();
|
|
1222
|
+
const trackRect = track.getBoundingClientRect();
|
|
1223
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
1224
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
1225
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
1226
|
+
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
1227
|
+
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
1228
|
+
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
1229
|
+
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
1230
|
+
};
|
|
1231
|
+
const onThumbPointerDown = (event) => {
|
|
1232
|
+
if (event.button !== 0) return;
|
|
1233
|
+
event.preventDefault();
|
|
1234
|
+
event.stopPropagation();
|
|
1235
|
+
entry.dragging = true;
|
|
1236
|
+
showEntry(entry);
|
|
1237
|
+
thumb.setPointerCapture(event.pointerId);
|
|
1238
|
+
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
1239
|
+
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
1240
|
+
const trackRect = track.getBoundingClientRect();
|
|
1241
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
1242
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
1243
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
1244
|
+
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
1245
|
+
const travel = Math.max(1, trackLength - thumbLength);
|
|
1246
|
+
const onPointerMove = (moveEvent) => {
|
|
1247
|
+
if (moveEvent.pointerId !== event.pointerId) return;
|
|
1248
|
+
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
1249
|
+
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
1250
|
+
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
1251
|
+
else target.scrollLeft = nextScroll;
|
|
1252
|
+
};
|
|
1253
|
+
const onPointerUp = (upEvent) => {
|
|
1254
|
+
if (upEvent.pointerId !== event.pointerId) return;
|
|
1255
|
+
entry.dragging = false;
|
|
1256
|
+
thumb.releasePointerCapture(event.pointerId);
|
|
1257
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
1258
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
1259
|
+
window.removeEventListener("pointercancel", onPointerUp);
|
|
1260
|
+
scheduleHide(entry);
|
|
1261
|
+
};
|
|
1262
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
1263
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
1264
|
+
window.addEventListener("pointercancel", onPointerUp);
|
|
1265
|
+
};
|
|
1266
|
+
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
1267
|
+
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
1268
|
+
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
1269
|
+
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
1270
|
+
return () => {
|
|
1271
|
+
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
1272
|
+
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
1273
|
+
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
1274
|
+
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
1275
|
+
};
|
|
1276
|
+
};
|
|
1277
|
+
const resizeObserver = new ResizeObserver((observedEntries) => {
|
|
1278
|
+
observedEntries.forEach(({ target }) => {
|
|
1279
|
+
const entry = entries.get(target);
|
|
1280
|
+
if (entry) updateEntry(entry);
|
|
1281
|
+
});
|
|
1282
|
+
});
|
|
1283
|
+
const addTarget = (target) => {
|
|
1284
|
+
if (entries.has(target)) return;
|
|
1285
|
+
const horizontal = createTrack("horizontal");
|
|
1286
|
+
const vertical = createTrack("vertical");
|
|
1287
|
+
layer.append(horizontal.track, vertical.track);
|
|
1288
|
+
const onPointerEnter = () => {
|
|
1289
|
+
const entry2 = entries.get(target);
|
|
1290
|
+
if (!entry2) return;
|
|
1291
|
+
entry2.hoveringTarget = true;
|
|
1292
|
+
showEntry(entry2);
|
|
1293
|
+
};
|
|
1294
|
+
const onPointerLeave = () => {
|
|
1295
|
+
const entry2 = entries.get(target);
|
|
1296
|
+
if (!entry2) return;
|
|
1297
|
+
entry2.hoveringTarget = false;
|
|
1298
|
+
scheduleHide(entry2);
|
|
1299
|
+
};
|
|
1300
|
+
const onScroll = () => {
|
|
1301
|
+
const entry2 = entries.get(target);
|
|
1302
|
+
if (!entry2) return;
|
|
1303
|
+
updateEntry(entry2);
|
|
1304
|
+
showEntry(entry2);
|
|
1305
|
+
scheduleHide(entry2, 700);
|
|
1306
|
+
};
|
|
1307
|
+
target.addEventListener("pointerenter", onPointerEnter);
|
|
1308
|
+
target.addEventListener("pointerleave", onPointerLeave);
|
|
1309
|
+
target.addEventListener("scroll", onScroll, { passive: true });
|
|
1310
|
+
const entry = {
|
|
1311
|
+
target,
|
|
1312
|
+
horizontalTrack: horizontal.track,
|
|
1313
|
+
horizontalThumb: horizontal.thumb,
|
|
1314
|
+
verticalTrack: vertical.track,
|
|
1315
|
+
verticalThumb: vertical.thumb,
|
|
1316
|
+
hideTimer: null,
|
|
1317
|
+
hoveringTarget: target.matches(":hover"),
|
|
1318
|
+
hoveringTrack: false,
|
|
1319
|
+
dragging: false,
|
|
1320
|
+
cleanup: () => void 0
|
|
1321
|
+
};
|
|
1322
|
+
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
1323
|
+
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
1324
|
+
entry.cleanup = () => {
|
|
1325
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1326
|
+
cleanupHorizontal();
|
|
1327
|
+
cleanupVertical();
|
|
1328
|
+
target.removeEventListener("pointerenter", onPointerEnter);
|
|
1329
|
+
target.removeEventListener("pointerleave", onPointerLeave);
|
|
1330
|
+
target.removeEventListener("scroll", onScroll);
|
|
1331
|
+
resizeObserver.unobserve(target);
|
|
1332
|
+
target.removeAttribute("data-sia-floating-scrollbar");
|
|
1333
|
+
horizontal.track.remove();
|
|
1334
|
+
vertical.track.remove();
|
|
1335
|
+
};
|
|
1336
|
+
entries.set(target, entry);
|
|
1337
|
+
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
1338
|
+
resizeObserver.observe(target);
|
|
1339
|
+
updateEntry(entry);
|
|
1340
|
+
if (entry.hoveringTarget) showEntry(entry);
|
|
1341
|
+
};
|
|
1342
|
+
const removeTarget = (target) => {
|
|
1343
|
+
const entry = entries.get(target);
|
|
1344
|
+
if (!entry) return;
|
|
1345
|
+
entry.cleanup();
|
|
1346
|
+
entries.delete(target);
|
|
1347
|
+
};
|
|
1348
|
+
const scanTargets = () => {
|
|
1349
|
+
scanFrame = 0;
|
|
1350
|
+
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
1351
|
+
const nextTargets = /* @__PURE__ */ new Set();
|
|
1352
|
+
candidates.forEach((target) => {
|
|
1353
|
+
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
1354
|
+
nextTargets.add(target);
|
|
1355
|
+
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
1356
|
+
}
|
|
1357
|
+
});
|
|
1358
|
+
entries.forEach((_entry, target) => {
|
|
1359
|
+
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
1360
|
+
else updateEntry(_entry);
|
|
1361
|
+
});
|
|
1362
|
+
};
|
|
1363
|
+
const scheduleScan = () => {
|
|
1364
|
+
if (scanFrame) return;
|
|
1365
|
+
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
1366
|
+
};
|
|
1367
|
+
const mutationObserver = new MutationObserver((mutations) => {
|
|
1368
|
+
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
1369
|
+
});
|
|
1370
|
+
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
1371
|
+
window.addEventListener("resize", scheduleScan);
|
|
1372
|
+
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
1373
|
+
scheduleScan();
|
|
1374
|
+
return () => {
|
|
1375
|
+
mutationObserver.disconnect();
|
|
1376
|
+
resizeObserver.disconnect();
|
|
1377
|
+
window.removeEventListener("resize", scheduleScan);
|
|
1378
|
+
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
1379
|
+
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
1380
|
+
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
1381
|
+
entries.forEach((entry) => entry.cleanup());
|
|
1382
|
+
entries.clear();
|
|
1383
|
+
layer.remove();
|
|
1384
|
+
};
|
|
1385
|
+
}, [disabled, targetRef]);
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1014
1389
|
// src/components/Select.tsx
|
|
1015
|
-
import { forwardRef as forwardRef3, useDeferredValue, useEffect as
|
|
1390
|
+
import { forwardRef as forwardRef3, useDeferredValue, useEffect as useEffect8, useId as useId5, useMemo as useMemo4, useRef as useRef7, useState as useState5 } from "react";
|
|
1016
1391
|
|
|
1017
1392
|
// src/components/OverflowTags.tsx
|
|
1018
1393
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useState as useState4 } from "react";
|
|
@@ -1158,7 +1533,7 @@ var Select = forwardRef3(function Select2({
|
|
|
1158
1533
|
const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
|
|
1159
1534
|
const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
|
|
1160
1535
|
const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
|
|
1161
|
-
|
|
1536
|
+
useEffect8(() => {
|
|
1162
1537
|
if (!open || popupMode === "modal") return void 0;
|
|
1163
1538
|
function closeFromOutside(event) {
|
|
1164
1539
|
const target = event.target;
|
|
@@ -1167,10 +1542,10 @@ var Select = forwardRef3(function Select2({
|
|
|
1167
1542
|
document.addEventListener("mousedown", closeFromOutside);
|
|
1168
1543
|
return () => document.removeEventListener("mousedown", closeFromOutside);
|
|
1169
1544
|
}, [open, popupMode]);
|
|
1170
|
-
|
|
1545
|
+
useEffect8(() => {
|
|
1171
1546
|
if (open && (showSearch || allowInput)) searchRef.current?.focus();
|
|
1172
1547
|
}, [allowInput, open, showSearch]);
|
|
1173
|
-
|
|
1548
|
+
useEffect8(() => {
|
|
1174
1549
|
if (disabled || loading) closeDropdown();
|
|
1175
1550
|
}, [disabled, loading]);
|
|
1176
1551
|
function firstEnabledIndex() {
|
|
@@ -1357,6 +1732,7 @@ var Select = forwardRef3(function Select2({
|
|
|
1357
1732
|
),
|
|
1358
1733
|
allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ jsx6("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ jsx6(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
1359
1734
|
/* @__PURE__ */ jsxs6(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
|
|
1735
|
+
/* @__PURE__ */ jsx6(FloatingScrollbarProvider, { targetRef: listRef }),
|
|
1360
1736
|
showSearch || allowInput ? /* @__PURE__ */ jsxs6("label", { className: "sia-select__search", children: [
|
|
1361
1737
|
/* @__PURE__ */ jsx6(Icon, { name: "search", size: 15 }),
|
|
1362
1738
|
/* @__PURE__ */ jsx6("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
|
|
@@ -1497,5 +1873,7 @@ export {
|
|
|
1497
1873
|
Modal2 as Modal,
|
|
1498
1874
|
SelectionPanel,
|
|
1499
1875
|
OverflowTags,
|
|
1876
|
+
useScrollbarProximity,
|
|
1877
|
+
FloatingScrollbarProvider,
|
|
1500
1878
|
Select
|
|
1501
1879
|
};
|
|
@@ -974,7 +974,8 @@ function MenuEntry({
|
|
|
974
974
|
item,
|
|
975
975
|
level,
|
|
976
976
|
parents,
|
|
977
|
-
props
|
|
977
|
+
props,
|
|
978
|
+
reserveIcon
|
|
978
979
|
}) {
|
|
979
980
|
const anchorRef = useRef2(null);
|
|
980
981
|
const closeTimerRef = useRef2(void 0);
|
|
@@ -1023,7 +1024,7 @@ function MenuEntry({
|
|
|
1023
1024
|
"aria-expanded": hasChildren ? isOpen : void 0,
|
|
1024
1025
|
onClick: (event) => hasChildren ? props.toggle(item.key) : props.select(item, path, event),
|
|
1025
1026
|
children: [
|
|
1026
|
-
|
|
1027
|
+
reserveIcon ? /* @__PURE__ */ jsx4("span", { className: "sia-menu__icon", "aria-hidden": !item.icon || void 0, children: item.icon }) : null,
|
|
1027
1028
|
!collapsed ? /* @__PURE__ */ jsx4("span", { className: "sia-menu__label", children: item.label }) : null,
|
|
1028
1029
|
!collapsed && item.extra ? /* @__PURE__ */ jsx4("span", { className: "sia-menu__extra", children: item.extra }) : null,
|
|
1029
1030
|
!collapsed && hasChildren ? /* @__PURE__ */ jsx4(Icon, { className: "sia-menu__expand-icon", name: "chevron-down", size: 13 }) : null
|
|
@@ -1047,19 +1048,23 @@ function MenuEntry({
|
|
|
1047
1048
|
}
|
|
1048
1049
|
);
|
|
1049
1050
|
}
|
|
1051
|
+
function hasMenuIcon(items) {
|
|
1052
|
+
return items.some((item) => item.type === "group" ? hasMenuIcon(item.children ?? []) : item.type !== "divider" && Boolean(item.icon));
|
|
1053
|
+
}
|
|
1050
1054
|
function MenuLevel({
|
|
1051
1055
|
items,
|
|
1052
1056
|
level,
|
|
1053
1057
|
parents,
|
|
1054
|
-
props
|
|
1058
|
+
props,
|
|
1059
|
+
reserveIcon = hasMenuIcon(items)
|
|
1055
1060
|
}) {
|
|
1056
1061
|
return /* @__PURE__ */ jsx4(Fragment3, { children: items.map((item, index) => {
|
|
1057
1062
|
if (item.type === "divider") return /* @__PURE__ */ jsx4("li", { className: "sia-menu__divider", role: "separator" }, item.key || `divider-${index}`);
|
|
1058
1063
|
if (item.type === "group") return /* @__PURE__ */ jsxs3("li", { className: "sia-menu__group", children: [
|
|
1059
1064
|
/* @__PURE__ */ jsx4("div", { className: "sia-menu__group-title", children: item.label }),
|
|
1060
|
-
/* @__PURE__ */ jsx4("ul", { role: "group", children: /* @__PURE__ */ jsx4(MenuLevel, { items: item.children ?? [], level: level + 1, parents: [...parents, item.key], props }) })
|
|
1065
|
+
/* @__PURE__ */ jsx4("ul", { role: "group", children: /* @__PURE__ */ jsx4(MenuLevel, { items: item.children ?? [], level: level + 1, parents: [...parents, item.key], props, reserveIcon }) })
|
|
1061
1066
|
] }, item.key);
|
|
1062
|
-
return /* @__PURE__ */ jsx4(MenuEntry, { item, level, parents, props }, item.key);
|
|
1067
|
+
return /* @__PURE__ */ jsx4(MenuEntry, { item, level, parents, props, reserveIcon }, item.key);
|
|
1063
1068
|
}) });
|
|
1064
1069
|
}
|
|
1065
1070
|
function Menu({
|