@sia.soul/sia-react-ui 0.1.14 → 0.1.17

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Select
3
- } from "./chunk-R3TYVU53.js";
3
+ } from "./chunk-VXSG4EAO.js";
4
4
  import {
5
5
  Icon,
6
6
  PopupPortal
@@ -5,7 +5,7 @@ import {
5
5
  Popover,
6
6
  Tooltip,
7
7
  useOverlayLifecycle
8
- } from "./chunk-R3TYVU53.js";
8
+ } from "./chunk-VXSG4EAO.js";
9
9
  import {
10
10
  Dropdown,
11
11
  Icon
@@ -76,6 +76,7 @@ function Tag({
76
76
  variant = "soft",
77
77
  icon,
78
78
  closable = false,
79
+ closeOnHover = false,
79
80
  disabled = false,
80
81
  onClose,
81
82
  className = "",
@@ -85,7 +86,7 @@ function Tag({
85
86
  return /* @__PURE__ */ jsxs2(
86
87
  "span",
87
88
  {
88
- className: `sia-tag sia-tag--${status} sia-tag--${variant}${compact ? " sia-tag--compact" : ""}${disabled ? " sia-tag--disabled" : ""} ${className}`.trim(),
89
+ className: `sia-tag${closable && closeOnHover ? " sia-tag--close-on-hover" : ""} sia-tag--${status} sia-tag--${variant}${compact ? " sia-tag--compact" : ""}${disabled ? " sia-tag--disabled" : ""} ${className}`.trim(),
89
90
  "aria-disabled": disabled || void 0,
90
91
  ...props,
91
92
  children: [
@@ -780,7 +780,7 @@ function openModal(config) {
780
780
  let currentOpen = true;
781
781
  let destroyed = false;
782
782
  let cleanupTimer;
783
- function cleanup() {
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(cleanup, MODAL_MOTION_DURATION);
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 useEffect6, useId as useId5, useMemo as useMemo4, useRef as useRef7, useState as useState5 } from "react";
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
- useEffect6(() => {
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
- useEffect6(() => {
1545
+ useEffect8(() => {
1171
1546
  if (open && (showSearch || allowInput)) searchRef.current?.focus();
1172
1547
  }, [allowInput, open, showSearch]);
1173
- useEffect6(() => {
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
  };
@@ -300,10 +300,12 @@ interface TagProps extends HTMLAttributes<HTMLSpanElement> {
300
300
  variant?: TagVariant;
301
301
  icon?: ReactNode;
302
302
  closable?: boolean;
303
+ /** 悬停或键盘聚焦时展开关闭按钮。 */
304
+ closeOnHover?: boolean;
303
305
  disabled?: boolean;
304
306
  onClose?: (event: MouseEvent<HTMLButtonElement>) => void;
305
307
  }
306
- declare function Tag({ status, compact, variant, icon, closable, disabled, onClose, className, children, ...props }: TagProps): react.JSX.Element;
308
+ declare function Tag({ status, compact, variant, icon, closable, closeOnHover, disabled, onClose, className, children, ...props }: TagProps): react.JSX.Element;
307
309
 
308
310
  type MenuMode = "vertical" | "horizontal" | "inline";
309
311
  type MenuTheme = "light" | "dark";
@@ -1077,4 +1079,4 @@ declare const FloatButton: react.ForwardRefExoticComponent<FloatButtonProps & re
1077
1079
  BackTop: typeof FloatButtonBackTop;
1078
1080
  };
1079
1081
 
1080
- export { Menu as $, type DropdownProps as A, type ButtonProps as B, Calendar as C, Dropdown as D, type DropdownTrigger as E, FILLED_ICON_NAMES as F, type FilledIconName as G, FloatButton as H, type FloatButtonBackTopProps as I, type FloatButtonGroupProps as J, type FloatButtonProps as K, type FloatButtonShape as L, type FloatingPlacement as M, type FloatingTrigger as N, type OverlayContainer as O, ICON_NAMES as P, Icon as Q, type IconName as R, type IconProps as S, type IconVariant as T, Image as U, ImagePreview as V, type ImagePreviewConfig as W, type ImagePreviewProps as X, type ImageProps as Y, Input as Z, type InputProps as _, type OverlayApiHandle as a, type TypographyTitleProps as a$, type MenuClickInfo as a0, type MenuItem as a1, type MenuMode as a2, type MenuProps as a3, type MenuTheme as a4, type MessageConfig as a5, type MessageHandle as a6, type MessageKey as a7, type MessageType as a8, Modal as a9, type TabItem as aA, Tabs as aB, type TabsContextMenuClickInfo as aC, type TabsOrientation as aD, type TabsPosition as aE, type TabsProps as aF, type TabsType as aG, Tag as aH, type TagProps as aI, type TagStatus as aJ, type TagVariant as aK, Timeline as aL, type TimelineItem as aM, type TimelineProps as aN, Tooltip as aO, type TooltipProps as aP, Tour as aQ, type TourProps as aR, type TourStep as aS, Tree as aT, type TreeDropPosition as aU, type TreeKey as aV, type TreeNode as aW, type TreeProps as aX, Typography as aY, type TypographyLinkProps as aZ, type TypographyProps as a_, type ModalActionResult as aa, type ModalOpenConfig as ab, type ModalProps as ac, type ModalType as ad, type NotificationConfig as ae, type NotificationPlacement as af, type NotificationType as ag, Popconfirm as ah, type PopconfirmProps as ai, Popover as aj, type PopoverProps as ak, Progress as al, type ProgressProps as am, type ProgressStatus as an, Rate as ao, type RateProps as ap, Segmented as aq, type SegmentedOption as ar, type SegmentedProps as as, type SegmentedValue as at, Spin as au, type SpinProps as av, type StepItem as aw, type StepStatus as ax, Steps as ay, type StepsProps as az, Badge as b, type TypographyType as b0, Upload as b1, type UploadChangeInfo as b2, type UploadDraggerProps as b3, type UploadFile as b4, type UploadFileStatus as b5, type UploadProps as b6, type UploadRequestOptions as b7, Watermark as b8, type WatermarkFont as b9, type WatermarkProps as ba, message as bb, notification as bc, type BadgeProps as c, type BadgeRibbonProps as d, type BadgeStatus as e, Breadcrumb as f, type BreadcrumbItem as g, type BreadcrumbProps as h, Button as i, type ButtonSize as j, type ButtonVariant as k, type CalendarProps as l, Card as m, type CardAccent as n, type CardProps as o, Carousel as p, type CarouselProps as q, type CarouselRef as r, Collapse as s, type CollapseItem as t, type CollapseKey as u, type CollapseProps as v, type DropdownButtonProps as w, type DropdownMenuProps as x, type DropdownOpenSource as y, type DropdownPlacement as z };
1082
+ export { type InputProps as $, type DropdownProps as A, type ButtonProps as B, Calendar as C, Dropdown as D, type DropdownTrigger as E, FILLED_ICON_NAMES as F, type FilledIconName as G, FloatButton as H, type FloatButtonBackTopProps as I, type FloatButtonGroupProps as J, type FloatButtonProps as K, type FloatButtonShape as L, type FloatingPlacement as M, type FloatingTrigger as N, type OverlayContainer as O, ICON_NAMES as P, Icon as Q, type IconName as R, type IconProps as S, type TagStatus as T, type IconVariant as U, Image as V, ImagePreview as W, type ImagePreviewConfig as X, type ImagePreviewProps as Y, type ImageProps as Z, Input as _, type OverlayApiHandle as a, type TypographyTitleProps as a$, Menu as a0, type MenuClickInfo as a1, type MenuItem as a2, type MenuMode as a3, type MenuProps as a4, type MenuTheme as a5, type MessageConfig as a6, type MessageHandle as a7, type MessageKey as a8, type MessageType as a9, type StepsProps as aA, type TabItem as aB, Tabs as aC, type TabsContextMenuClickInfo as aD, type TabsOrientation as aE, type TabsPosition as aF, type TabsProps as aG, type TabsType as aH, Tag as aI, type TagProps as aJ, type TagVariant as aK, Timeline as aL, type TimelineItem as aM, type TimelineProps as aN, Tooltip as aO, type TooltipProps as aP, Tour as aQ, type TourProps as aR, type TourStep as aS, Tree as aT, type TreeDropPosition as aU, type TreeKey as aV, type TreeNode as aW, type TreeProps as aX, Typography as aY, type TypographyLinkProps as aZ, type TypographyProps as a_, Modal as aa, type ModalActionResult as ab, type ModalOpenConfig as ac, type ModalProps as ad, type ModalType as ae, type NotificationConfig as af, type NotificationPlacement as ag, type NotificationType as ah, Popconfirm as ai, type PopconfirmProps as aj, Popover as ak, type PopoverProps as al, Progress as am, type ProgressProps as an, type ProgressStatus as ao, Rate as ap, type RateProps as aq, Segmented as ar, type SegmentedOption as as, type SegmentedProps as at, type SegmentedValue as au, Spin as av, type SpinProps as aw, type StepItem as ax, type StepStatus as ay, Steps as az, type ButtonSize as b, type TypographyType as b0, Upload as b1, type UploadChangeInfo as b2, type UploadDraggerProps as b3, type UploadFile as b4, type UploadFileStatus as b5, type UploadProps as b6, type UploadRequestOptions as b7, Watermark as b8, type WatermarkFont as b9, type WatermarkProps as ba, message as bb, notification as bc, type BadgeProps as c, Badge as d, type BadgeRibbonProps as e, type BadgeStatus as f, Breadcrumb as g, type BreadcrumbItem as h, type BreadcrumbProps as i, Button as j, type ButtonVariant as k, type CalendarProps as l, Card as m, type CardAccent as n, type CardProps as o, Carousel as p, type CarouselProps as q, type CarouselRef as r, Collapse as s, type CollapseItem as t, type CollapseKey as u, type CollapseProps as v, type DropdownButtonProps as w, type DropdownMenuProps as x, type DropdownOpenSource as y, type DropdownPlacement as z };
@@ -300,10 +300,12 @@ interface TagProps extends HTMLAttributes<HTMLSpanElement> {
300
300
  variant?: TagVariant;
301
301
  icon?: ReactNode;
302
302
  closable?: boolean;
303
+ /** 悬停或键盘聚焦时展开关闭按钮。 */
304
+ closeOnHover?: boolean;
303
305
  disabled?: boolean;
304
306
  onClose?: (event: MouseEvent<HTMLButtonElement>) => void;
305
307
  }
306
- declare function Tag({ status, compact, variant, icon, closable, disabled, onClose, className, children, ...props }: TagProps): react.JSX.Element;
308
+ declare function Tag({ status, compact, variant, icon, closable, closeOnHover, disabled, onClose, className, children, ...props }: TagProps): react.JSX.Element;
307
309
 
308
310
  type MenuMode = "vertical" | "horizontal" | "inline";
309
311
  type MenuTheme = "light" | "dark";
@@ -1077,4 +1079,4 @@ declare const FloatButton: react.ForwardRefExoticComponent<FloatButtonProps & re
1077
1079
  BackTop: typeof FloatButtonBackTop;
1078
1080
  };
1079
1081
 
1080
- export { Menu as $, type DropdownProps as A, type ButtonProps as B, Calendar as C, Dropdown as D, type DropdownTrigger as E, FILLED_ICON_NAMES as F, type FilledIconName as G, FloatButton as H, type FloatButtonBackTopProps as I, type FloatButtonGroupProps as J, type FloatButtonProps as K, type FloatButtonShape as L, type FloatingPlacement as M, type FloatingTrigger as N, type OverlayContainer as O, ICON_NAMES as P, Icon as Q, type IconName as R, type IconProps as S, type IconVariant as T, Image as U, ImagePreview as V, type ImagePreviewConfig as W, type ImagePreviewProps as X, type ImageProps as Y, Input as Z, type InputProps as _, type OverlayApiHandle as a, type TypographyTitleProps as a$, type MenuClickInfo as a0, type MenuItem as a1, type MenuMode as a2, type MenuProps as a3, type MenuTheme as a4, type MessageConfig as a5, type MessageHandle as a6, type MessageKey as a7, type MessageType as a8, Modal as a9, type TabItem as aA, Tabs as aB, type TabsContextMenuClickInfo as aC, type TabsOrientation as aD, type TabsPosition as aE, type TabsProps as aF, type TabsType as aG, Tag as aH, type TagProps as aI, type TagStatus as aJ, type TagVariant as aK, Timeline as aL, type TimelineItem as aM, type TimelineProps as aN, Tooltip as aO, type TooltipProps as aP, Tour as aQ, type TourProps as aR, type TourStep as aS, Tree as aT, type TreeDropPosition as aU, type TreeKey as aV, type TreeNode as aW, type TreeProps as aX, Typography as aY, type TypographyLinkProps as aZ, type TypographyProps as a_, type ModalActionResult as aa, type ModalOpenConfig as ab, type ModalProps as ac, type ModalType as ad, type NotificationConfig as ae, type NotificationPlacement as af, type NotificationType as ag, Popconfirm as ah, type PopconfirmProps as ai, Popover as aj, type PopoverProps as ak, Progress as al, type ProgressProps as am, type ProgressStatus as an, Rate as ao, type RateProps as ap, Segmented as aq, type SegmentedOption as ar, type SegmentedProps as as, type SegmentedValue as at, Spin as au, type SpinProps as av, type StepItem as aw, type StepStatus as ax, Steps as ay, type StepsProps as az, Badge as b, type TypographyType as b0, Upload as b1, type UploadChangeInfo as b2, type UploadDraggerProps as b3, type UploadFile as b4, type UploadFileStatus as b5, type UploadProps as b6, type UploadRequestOptions as b7, Watermark as b8, type WatermarkFont as b9, type WatermarkProps as ba, message as bb, notification as bc, type BadgeProps as c, type BadgeRibbonProps as d, type BadgeStatus as e, Breadcrumb as f, type BreadcrumbItem as g, type BreadcrumbProps as h, Button as i, type ButtonSize as j, type ButtonVariant as k, type CalendarProps as l, Card as m, type CardAccent as n, type CardProps as o, Carousel as p, type CarouselProps as q, type CarouselRef as r, Collapse as s, type CollapseItem as t, type CollapseKey as u, type CollapseProps as v, type DropdownButtonProps as w, type DropdownMenuProps as x, type DropdownOpenSource as y, type DropdownPlacement as z };
1082
+ export { type InputProps as $, type DropdownProps as A, type ButtonProps as B, Calendar as C, Dropdown as D, type DropdownTrigger as E, FILLED_ICON_NAMES as F, type FilledIconName as G, FloatButton as H, type FloatButtonBackTopProps as I, type FloatButtonGroupProps as J, type FloatButtonProps as K, type FloatButtonShape as L, type FloatingPlacement as M, type FloatingTrigger as N, type OverlayContainer as O, ICON_NAMES as P, Icon as Q, type IconName as R, type IconProps as S, type TagStatus as T, type IconVariant as U, Image as V, ImagePreview as W, type ImagePreviewConfig as X, type ImagePreviewProps as Y, type ImageProps as Z, Input as _, type OverlayApiHandle as a, type TypographyTitleProps as a$, Menu as a0, type MenuClickInfo as a1, type MenuItem as a2, type MenuMode as a3, type MenuProps as a4, type MenuTheme as a5, type MessageConfig as a6, type MessageHandle as a7, type MessageKey as a8, type MessageType as a9, type StepsProps as aA, type TabItem as aB, Tabs as aC, type TabsContextMenuClickInfo as aD, type TabsOrientation as aE, type TabsPosition as aF, type TabsProps as aG, type TabsType as aH, Tag as aI, type TagProps as aJ, type TagVariant as aK, Timeline as aL, type TimelineItem as aM, type TimelineProps as aN, Tooltip as aO, type TooltipProps as aP, Tour as aQ, type TourProps as aR, type TourStep as aS, Tree as aT, type TreeDropPosition as aU, type TreeKey as aV, type TreeNode as aW, type TreeProps as aX, Typography as aY, type TypographyLinkProps as aZ, type TypographyProps as a_, Modal as aa, type ModalActionResult as ab, type ModalOpenConfig as ac, type ModalProps as ad, type ModalType as ae, type NotificationConfig as af, type NotificationPlacement as ag, type NotificationType as ah, Popconfirm as ai, type PopconfirmProps as aj, Popover as ak, type PopoverProps as al, Progress as am, type ProgressProps as an, type ProgressStatus as ao, Rate as ap, type RateProps as aq, Segmented as ar, type SegmentedOption as as, type SegmentedProps as at, type SegmentedValue as au, Spin as av, type SpinProps as aw, type StepItem as ax, type StepStatus as ay, Steps as az, type ButtonSize as b, type TypographyType as b0, Upload as b1, type UploadChangeInfo as b2, type UploadDraggerProps as b3, type UploadFile as b4, type UploadFileStatus as b5, type UploadProps as b6, type UploadRequestOptions as b7, Watermark as b8, type WatermarkFont as b9, type WatermarkProps as ba, message as bb, notification as bc, type BadgeProps as c, Badge as d, type BadgeRibbonProps as e, type BadgeStatus as f, Breadcrumb as g, type BreadcrumbItem as h, type BreadcrumbProps as i, Button as j, type ButtonVariant as k, type CalendarProps as l, Card as m, type CardAccent as n, type CardProps as o, Carousel as p, type CarouselProps as q, type CarouselRef as r, Collapse as s, type CollapseItem as t, type CollapseKey as u, type CollapseProps as v, type DropdownButtonProps as w, type DropdownMenuProps as x, type DropdownOpenSource as y, type DropdownPlacement as z };