@sia.soul/sia-react-ui 0.1.15 → 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.
package/dist/core.cjs CHANGED
@@ -2295,7 +2295,7 @@ function useFloatingPlaceholder({ mode, placeholder, filled, active = false }) {
2295
2295
  }
2296
2296
 
2297
2297
  // src/components/Select.tsx
2298
- var import_react18 = require("react");
2298
+ var import_react20 = require("react");
2299
2299
 
2300
2300
  // src/components/Modal.tsx
2301
2301
  var import_react14 = require("react");
@@ -2458,7 +2458,7 @@ function openModal(config) {
2458
2458
  let currentOpen = true;
2459
2459
  let destroyed = false;
2460
2460
  let cleanupTimer;
2461
- function cleanup() {
2461
+ function cleanup2() {
2462
2462
  if (destroyed) return;
2463
2463
  destroyed = true;
2464
2464
  if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
@@ -2470,7 +2470,7 @@ function openModal(config) {
2470
2470
  if (destroyed || !currentOpen) return;
2471
2471
  currentOpen = false;
2472
2472
  render();
2473
- cleanupTimer = window.setTimeout(cleanup, MODAL_MOTION_DURATION);
2473
+ cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
2474
2474
  }
2475
2475
  function render() {
2476
2476
  root.render(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
@@ -2840,13 +2840,388 @@ function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName
2840
2840
  ] });
2841
2841
  }
2842
2842
 
2843
+ // src/components/FloatingScrollbarProvider.tsx
2844
+ var import_react19 = require("react");
2845
+
2846
+ // src/components/useScrollbarProximity.ts
2847
+ var import_react18 = require("react");
2848
+ var users = 0;
2849
+ var cleanup;
2850
+ function useScrollbarProximity() {
2851
+ (0, import_react18.useEffect)(() => {
2852
+ if (users++ === 0) {
2853
+ let frame = 0;
2854
+ let x = -Infinity;
2855
+ let y = -Infinity;
2856
+ const nearby = /* @__PURE__ */ new Set();
2857
+ const clear = () => {
2858
+ nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
2859
+ nearby.clear();
2860
+ };
2861
+ const update = () => {
2862
+ frame = 0;
2863
+ const next = /* @__PURE__ */ new Set();
2864
+ document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
2865
+ const rect = track.getBoundingClientRect();
2866
+ const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
2867
+ if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
2868
+ next.add(track);
2869
+ if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
2870
+ }
2871
+ });
2872
+ nearby.forEach((track) => {
2873
+ if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
2874
+ });
2875
+ nearby.clear();
2876
+ next.forEach((track) => nearby.add(track));
2877
+ };
2878
+ const move = (event) => {
2879
+ if (event.pointerType === "touch") return;
2880
+ x = event.clientX;
2881
+ y = event.clientY;
2882
+ if (!frame) frame = requestAnimationFrame(update);
2883
+ };
2884
+ const leave = () => {
2885
+ x = y = -Infinity;
2886
+ clear();
2887
+ };
2888
+ document.addEventListener("pointermove", move, { passive: true });
2889
+ document.documentElement.addEventListener("pointerleave", leave);
2890
+ window.addEventListener("blur", leave);
2891
+ cleanup = () => {
2892
+ if (frame) cancelAnimationFrame(frame);
2893
+ document.removeEventListener("pointermove", move);
2894
+ document.documentElement.removeEventListener("pointerleave", leave);
2895
+ window.removeEventListener("blur", leave);
2896
+ clear();
2897
+ };
2898
+ }
2899
+ return () => {
2900
+ if (--users === 0) {
2901
+ cleanup?.();
2902
+ cleanup = void 0;
2903
+ }
2904
+ };
2905
+ }, []);
2906
+ }
2907
+
2908
+ // src/components/FloatingScrollbarProvider.tsx
2909
+ var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
2910
+ var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
2911
+ function isRootScroller(target) {
2912
+ return target === document.scrollingElement || target === document.documentElement;
2913
+ }
2914
+ function canScroll(target, axis) {
2915
+ if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
2916
+ if (isRootScroller(target)) {
2917
+ return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
2918
+ }
2919
+ const style = getComputedStyle(target);
2920
+ const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
2921
+ const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
2922
+ return hasOverflow && scrollableOverflow.has(overflow);
2923
+ }
2924
+ function visibleRect(target) {
2925
+ if (isRootScroller(target)) {
2926
+ return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
2927
+ }
2928
+ const ownRect = target.getBoundingClientRect();
2929
+ let top = Math.max(0, ownRect.top);
2930
+ let right = Math.min(window.innerWidth, ownRect.right);
2931
+ let bottom = Math.min(window.innerHeight, ownRect.bottom);
2932
+ let left = Math.max(0, ownRect.left);
2933
+ let parent = target.parentElement;
2934
+ while (parent && parent !== document.body && parent !== document.documentElement) {
2935
+ const style = getComputedStyle(parent);
2936
+ const clipX = clippingOverflow.has(style.overflowX);
2937
+ const clipY = clippingOverflow.has(style.overflowY);
2938
+ if (clipX || clipY) {
2939
+ const rect = parent.getBoundingClientRect();
2940
+ if (clipX) {
2941
+ left = Math.max(left, rect.left);
2942
+ right = Math.min(right, rect.right);
2943
+ }
2944
+ if (clipY) {
2945
+ top = Math.max(top, rect.top);
2946
+ bottom = Math.min(bottom, rect.bottom);
2947
+ }
2948
+ }
2949
+ parent = parent.parentElement;
2950
+ }
2951
+ return {
2952
+ top,
2953
+ right,
2954
+ bottom,
2955
+ left,
2956
+ width: Math.max(0, right - left),
2957
+ height: Math.max(0, bottom - top)
2958
+ };
2959
+ }
2960
+ function createTrack(axis) {
2961
+ const track = document.createElement("div");
2962
+ const thumb = document.createElement("div");
2963
+ track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
2964
+ thumb.className = "sia-floating-scrollbar__thumb";
2965
+ track.dataset.axis = axis;
2966
+ track.setAttribute("aria-hidden", "true");
2967
+ track.append(thumb);
2968
+ return { track, thumb };
2969
+ }
2970
+ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
2971
+ useScrollbarProximity();
2972
+ (0, import_react19.useEffect)(() => {
2973
+ if (disabled) return;
2974
+ const layer = document.createElement("div");
2975
+ layer.className = "sia-floating-scrollbar-layer";
2976
+ layer.setAttribute("aria-hidden", "true");
2977
+ document.body.append(layer);
2978
+ const entries = /* @__PURE__ */ new Map();
2979
+ let scanFrame = 0;
2980
+ let updateFrame = 0;
2981
+ const setEntryVisible = (entry, visible) => {
2982
+ entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
2983
+ entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
2984
+ };
2985
+ const showEntry = (entry) => {
2986
+ if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
2987
+ entry.hideTimer = null;
2988
+ setEntryVisible(entry, true);
2989
+ };
2990
+ const scheduleHide = (entry, delay = 500) => {
2991
+ if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
2992
+ entry.hideTimer = window.setTimeout(() => {
2993
+ entry.hideTimer = null;
2994
+ if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
2995
+ }, delay);
2996
+ };
2997
+ const updateEntry = (entry) => {
2998
+ const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
2999
+ const hasHorizontal = canScroll(target, "horizontal");
3000
+ const hasVertical = canScroll(target, "vertical");
3001
+ const rect = visibleRect(target);
3002
+ const thickness = 10;
3003
+ horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
3004
+ verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
3005
+ if (!horizontalTrack.hidden) {
3006
+ const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
3007
+ const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
3008
+ const travel = Math.max(0, trackWidth - thumbWidth);
3009
+ const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
3010
+ horizontalTrack.style.left = `${rect.left}px`;
3011
+ horizontalTrack.style.top = `${rect.bottom - thickness}px`;
3012
+ horizontalTrack.style.width = `${trackWidth}px`;
3013
+ horizontalTrack.style.height = `${thickness}px`;
3014
+ horizontalThumb.style.width = `${thumbWidth}px`;
3015
+ horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
3016
+ }
3017
+ if (!verticalTrack.hidden) {
3018
+ const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
3019
+ const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
3020
+ const travel = Math.max(0, trackHeight - thumbHeight);
3021
+ const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
3022
+ verticalTrack.style.left = `${rect.right - thickness}px`;
3023
+ verticalTrack.style.top = `${rect.top}px`;
3024
+ verticalTrack.style.width = `${thickness}px`;
3025
+ verticalTrack.style.height = `${trackHeight}px`;
3026
+ verticalThumb.style.height = `${thumbHeight}px`;
3027
+ verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
3028
+ }
3029
+ };
3030
+ const scheduleUpdateAll = () => {
3031
+ if (updateFrame) return;
3032
+ updateFrame = window.requestAnimationFrame(() => {
3033
+ updateFrame = 0;
3034
+ entries.forEach(updateEntry);
3035
+ });
3036
+ };
3037
+ const bindTrackDrag = (entry, axis, track, thumb) => {
3038
+ const target = entry.target;
3039
+ const onTrackPointerEnter = () => {
3040
+ entry.hoveringTrack = true;
3041
+ showEntry(entry);
3042
+ };
3043
+ const onTrackPointerLeave = () => {
3044
+ entry.hoveringTrack = false;
3045
+ scheduleHide(entry);
3046
+ };
3047
+ const onTrackPointerDown = (event) => {
3048
+ if (event.target === thumb || event.button !== 0) return;
3049
+ event.preventDefault();
3050
+ event.stopPropagation();
3051
+ const trackRect = track.getBoundingClientRect();
3052
+ const thumbRect = thumb.getBoundingClientRect();
3053
+ const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
3054
+ const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
3055
+ const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
3056
+ const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
3057
+ if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
3058
+ else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
3059
+ };
3060
+ const onThumbPointerDown = (event) => {
3061
+ if (event.button !== 0) return;
3062
+ event.preventDefault();
3063
+ event.stopPropagation();
3064
+ entry.dragging = true;
3065
+ showEntry(entry);
3066
+ thumb.setPointerCapture(event.pointerId);
3067
+ const startPointer = axis === "vertical" ? event.clientY : event.clientX;
3068
+ const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
3069
+ const trackRect = track.getBoundingClientRect();
3070
+ const thumbRect = thumb.getBoundingClientRect();
3071
+ const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
3072
+ const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
3073
+ const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
3074
+ const travel = Math.max(1, trackLength - thumbLength);
3075
+ const onPointerMove = (moveEvent) => {
3076
+ if (moveEvent.pointerId !== event.pointerId) return;
3077
+ const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
3078
+ const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
3079
+ if (axis === "vertical") target.scrollTop = nextScroll;
3080
+ else target.scrollLeft = nextScroll;
3081
+ };
3082
+ const onPointerUp = (upEvent) => {
3083
+ if (upEvent.pointerId !== event.pointerId) return;
3084
+ entry.dragging = false;
3085
+ thumb.releasePointerCapture(event.pointerId);
3086
+ window.removeEventListener("pointermove", onPointerMove);
3087
+ window.removeEventListener("pointerup", onPointerUp);
3088
+ window.removeEventListener("pointercancel", onPointerUp);
3089
+ scheduleHide(entry);
3090
+ };
3091
+ window.addEventListener("pointermove", onPointerMove);
3092
+ window.addEventListener("pointerup", onPointerUp);
3093
+ window.addEventListener("pointercancel", onPointerUp);
3094
+ };
3095
+ track.addEventListener("pointerenter", onTrackPointerEnter);
3096
+ track.addEventListener("pointerleave", onTrackPointerLeave);
3097
+ track.addEventListener("pointerdown", onTrackPointerDown);
3098
+ thumb.addEventListener("pointerdown", onThumbPointerDown);
3099
+ return () => {
3100
+ track.removeEventListener("pointerenter", onTrackPointerEnter);
3101
+ track.removeEventListener("pointerleave", onTrackPointerLeave);
3102
+ track.removeEventListener("pointerdown", onTrackPointerDown);
3103
+ thumb.removeEventListener("pointerdown", onThumbPointerDown);
3104
+ };
3105
+ };
3106
+ const resizeObserver = new ResizeObserver((observedEntries) => {
3107
+ observedEntries.forEach(({ target }) => {
3108
+ const entry = entries.get(target);
3109
+ if (entry) updateEntry(entry);
3110
+ });
3111
+ });
3112
+ const addTarget = (target) => {
3113
+ if (entries.has(target)) return;
3114
+ const horizontal = createTrack("horizontal");
3115
+ const vertical = createTrack("vertical");
3116
+ layer.append(horizontal.track, vertical.track);
3117
+ const onPointerEnter = () => {
3118
+ const entry2 = entries.get(target);
3119
+ if (!entry2) return;
3120
+ entry2.hoveringTarget = true;
3121
+ showEntry(entry2);
3122
+ };
3123
+ const onPointerLeave = () => {
3124
+ const entry2 = entries.get(target);
3125
+ if (!entry2) return;
3126
+ entry2.hoveringTarget = false;
3127
+ scheduleHide(entry2);
3128
+ };
3129
+ const onScroll = () => {
3130
+ const entry2 = entries.get(target);
3131
+ if (!entry2) return;
3132
+ updateEntry(entry2);
3133
+ showEntry(entry2);
3134
+ scheduleHide(entry2, 700);
3135
+ };
3136
+ target.addEventListener("pointerenter", onPointerEnter);
3137
+ target.addEventListener("pointerleave", onPointerLeave);
3138
+ target.addEventListener("scroll", onScroll, { passive: true });
3139
+ const entry = {
3140
+ target,
3141
+ horizontalTrack: horizontal.track,
3142
+ horizontalThumb: horizontal.thumb,
3143
+ verticalTrack: vertical.track,
3144
+ verticalThumb: vertical.thumb,
3145
+ hideTimer: null,
3146
+ hoveringTarget: target.matches(":hover"),
3147
+ hoveringTrack: false,
3148
+ dragging: false,
3149
+ cleanup: () => void 0
3150
+ };
3151
+ const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
3152
+ const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
3153
+ entry.cleanup = () => {
3154
+ if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
3155
+ cleanupHorizontal();
3156
+ cleanupVertical();
3157
+ target.removeEventListener("pointerenter", onPointerEnter);
3158
+ target.removeEventListener("pointerleave", onPointerLeave);
3159
+ target.removeEventListener("scroll", onScroll);
3160
+ resizeObserver.unobserve(target);
3161
+ target.removeAttribute("data-sia-floating-scrollbar");
3162
+ horizontal.track.remove();
3163
+ vertical.track.remove();
3164
+ };
3165
+ entries.set(target, entry);
3166
+ target.setAttribute("data-sia-floating-scrollbar", "");
3167
+ resizeObserver.observe(target);
3168
+ updateEntry(entry);
3169
+ if (entry.hoveringTarget) showEntry(entry);
3170
+ };
3171
+ const removeTarget = (target) => {
3172
+ const entry = entries.get(target);
3173
+ if (!entry) return;
3174
+ entry.cleanup();
3175
+ entries.delete(target);
3176
+ };
3177
+ const scanTargets = () => {
3178
+ scanFrame = 0;
3179
+ const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
3180
+ const nextTargets = /* @__PURE__ */ new Set();
3181
+ candidates.forEach((target) => {
3182
+ if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
3183
+ nextTargets.add(target);
3184
+ if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
3185
+ }
3186
+ });
3187
+ entries.forEach((_entry, target) => {
3188
+ if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
3189
+ else updateEntry(_entry);
3190
+ });
3191
+ };
3192
+ const scheduleScan = () => {
3193
+ if (scanFrame) return;
3194
+ scanFrame = window.requestAnimationFrame(scanTargets);
3195
+ };
3196
+ const mutationObserver = new MutationObserver((mutations) => {
3197
+ if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
3198
+ });
3199
+ mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
3200
+ window.addEventListener("resize", scheduleScan);
3201
+ window.addEventListener("scroll", scheduleUpdateAll, true);
3202
+ scheduleScan();
3203
+ return () => {
3204
+ mutationObserver.disconnect();
3205
+ resizeObserver.disconnect();
3206
+ window.removeEventListener("resize", scheduleScan);
3207
+ window.removeEventListener("scroll", scheduleUpdateAll, true);
3208
+ if (scanFrame) window.cancelAnimationFrame(scanFrame);
3209
+ if (updateFrame) window.cancelAnimationFrame(updateFrame);
3210
+ entries.forEach((entry) => entry.cleanup());
3211
+ entries.clear();
3212
+ layer.remove();
3213
+ };
3214
+ }, [disabled, targetRef]);
3215
+ return null;
3216
+ }
3217
+
2843
3218
  // src/components/Select.tsx
2844
3219
  var import_jsx_runtime19 = require("react/jsx-runtime");
2845
3220
  function defaultFilterOption(query, option) {
2846
3221
  const keyword = query.toLowerCase();
2847
3222
  return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
2848
3223
  }
2849
- var Select = (0, import_react18.forwardRef)(function Select2({
3224
+ var Select = (0, import_react20.forwardRef)(function Select2({
2850
3225
  options,
2851
3226
  mode = "single",
2852
3227
  popupMode = "dropdown",
@@ -2883,20 +3258,20 @@ var Select = (0, import_react18.forwardRef)(function Select2({
2883
3258
  ...props
2884
3259
  }, forwardedRef) {
2885
3260
  const size = useControlSize(sizeProp);
2886
- const fallbackId = (0, import_react18.useId)();
3261
+ const fallbackId = (0, import_react20.useId)();
2887
3262
  const selectId = id ?? fallbackId;
2888
3263
  const listboxId = `${selectId}-listbox`;
2889
- const rootRef = (0, import_react18.useRef)(null);
2890
- const popupRef = (0, import_react18.useRef)(null);
2891
- const searchRef = (0, import_react18.useRef)(null);
2892
- const listRef = (0, import_react18.useRef)(null);
2893
- const [open, setOpen] = (0, import_react18.useState)(false);
2894
- const [modalValues, setModalValues] = (0, import_react18.useState)([]);
2895
- const [selectedOnly, setSelectedOnly] = (0, import_react18.useState)(false);
2896
- const [query, setQuery] = (0, import_react18.useState)("");
2897
- const [activeIndex, setActiveIndex] = (0, import_react18.useState)(-1);
2898
- const [scrollTop, setScrollTop] = (0, import_react18.useState)(0);
2899
- const deferredQuery = (0, import_react18.useDeferredValue)(query.trim());
3264
+ const rootRef = (0, import_react20.useRef)(null);
3265
+ const popupRef = (0, import_react20.useRef)(null);
3266
+ const searchRef = (0, import_react20.useRef)(null);
3267
+ const listRef = (0, import_react20.useRef)(null);
3268
+ const [open, setOpen] = (0, import_react20.useState)(false);
3269
+ const [modalValues, setModalValues] = (0, import_react20.useState)([]);
3270
+ const [selectedOnly, setSelectedOnly] = (0, import_react20.useState)(false);
3271
+ const [query, setQuery] = (0, import_react20.useState)("");
3272
+ const [activeIndex, setActiveIndex] = (0, import_react20.useState)(-1);
3273
+ const [scrollTop, setScrollTop] = (0, import_react20.useState)(0);
3274
+ const deferredQuery = (0, import_react20.useDeferredValue)(query.trim());
2900
3275
  const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
2901
3276
  const [currentValue, setCurrentValue] = useControllableState({
2902
3277
  value,
@@ -2911,19 +3286,19 @@ var Select = (0, import_react18.forwardRef)(function Select2({
2911
3286
  }
2912
3287
  }
2913
3288
  });
2914
- const selectedValues = (0, import_react18.useMemo)(() => {
3289
+ const selectedValues = (0, import_react20.useMemo)(() => {
2915
3290
  if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
2916
3291
  return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
2917
3292
  }, [currentValue, mode]);
2918
- const selectedValueSet = (0, import_react18.useMemo)(() => new Set(selectedValues), [selectedValues]);
2919
- const availableOptions = (0, import_react18.useMemo)(() => {
3293
+ const selectedValueSet = (0, import_react20.useMemo)(() => new Set(selectedValues), [selectedValues]);
3294
+ const availableOptions = (0, import_react20.useMemo)(() => {
2920
3295
  if (!allowInput) return options;
2921
3296
  const optionValueSet = new Set(options.map((option) => option.value));
2922
3297
  const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
2923
3298
  return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
2924
3299
  }, [allowInput, options, selectedValues]);
2925
- const selectedOptions = (0, import_react18.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
2926
- const filteredOptions = (0, import_react18.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
3300
+ const selectedOptions = (0, import_react20.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
3301
+ const filteredOptions = (0, import_react20.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
2927
3302
  const inputValue = query.trim();
2928
3303
  const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
2929
3304
  const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
@@ -2937,7 +3312,7 @@ var Select = (0, import_react18.forwardRef)(function Select2({
2937
3312
  const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
2938
3313
  const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
2939
3314
  const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
2940
- (0, import_react18.useEffect)(() => {
3315
+ (0, import_react20.useEffect)(() => {
2941
3316
  if (!open || popupMode === "modal") return void 0;
2942
3317
  function closeFromOutside(event) {
2943
3318
  const target = event.target;
@@ -2946,10 +3321,10 @@ var Select = (0, import_react18.forwardRef)(function Select2({
2946
3321
  document.addEventListener("mousedown", closeFromOutside);
2947
3322
  return () => document.removeEventListener("mousedown", closeFromOutside);
2948
3323
  }, [open, popupMode]);
2949
- (0, import_react18.useEffect)(() => {
3324
+ (0, import_react20.useEffect)(() => {
2950
3325
  if (open && (showSearch || allowInput)) searchRef.current?.focus();
2951
3326
  }, [allowInput, open, showSearch]);
2952
- (0, import_react18.useEffect)(() => {
3327
+ (0, import_react20.useEffect)(() => {
2953
3328
  if (disabled || loading) closeDropdown();
2954
3329
  }, [disabled, loading]);
2955
3330
  function firstEnabledIndex() {
@@ -3136,6 +3511,7 @@ var Select = (0, import_react18.forwardRef)(function Select2({
3136
3511
  ),
3137
3512
  allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
3138
3513
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
3514
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FloatingScrollbarProvider, { targetRef: listRef }),
3139
3515
  showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "sia-select__search", children: [
3140
3516
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 15 }),
3141
3517
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
@@ -3266,7 +3642,7 @@ var Select = (0, import_react18.forwardRef)(function Select2({
3266
3642
  });
3267
3643
 
3268
3644
  // src/components/Upload.tsx
3269
- var import_react19 = require("react");
3645
+ var import_react21 = require("react");
3270
3646
  var import_jsx_runtime20 = require("react/jsx-runtime");
3271
3647
  var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
3272
3648
  function UploadRoot({
@@ -3289,9 +3665,9 @@ function UploadRoot({
3289
3665
  onDrop,
3290
3666
  ...props
3291
3667
  }) {
3292
- const inputRef = (0, import_react19.useRef)(null);
3293
- const filesRef = (0, import_react19.useRef)(fileList ?? defaultFileList);
3294
- const id = (0, import_react19.useId)();
3668
+ const inputRef = (0, import_react21.useRef)(null);
3669
+ const filesRef = (0, import_react21.useRef)(fileList ?? defaultFileList);
3670
+ const id = (0, import_react21.useId)();
3295
3671
  const [files, setFiles] = useControllableState({ value: fileList, defaultValue: defaultFileList });
3296
3672
  filesRef.current = files;
3297
3673
  function emit(file, nextList) {
@@ -3514,12 +3890,12 @@ function Breadcrumb({ items, separator = "/", itemRender, className = "", ...pro
3514
3890
  }
3515
3891
 
3516
3892
  // src/components/Typography.tsx
3517
- var import_react21 = require("react");
3893
+ var import_react23 = require("react");
3518
3894
 
3519
3895
  // src/components/TextArea.tsx
3520
- var import_react20 = require("react");
3896
+ var import_react22 = require("react");
3521
3897
  var import_jsx_runtime23 = require("react/jsx-runtime");
3522
- var TextArea = (0, import_react20.forwardRef)(function TextArea2({
3898
+ var TextArea = (0, import_react22.forwardRef)(function TextArea2({
3523
3899
  label,
3524
3900
  hint,
3525
3901
  status = "default",
@@ -3537,9 +3913,9 @@ var TextArea = (0, import_react20.forwardRef)(function TextArea2({
3537
3913
  ...props
3538
3914
  }, ref) {
3539
3915
  const size = useControlSize(sizeProp);
3540
- const fallbackId = (0, import_react20.useId)();
3916
+ const fallbackId = (0, import_react22.useId)();
3541
3917
  const textAreaId = id ?? fallbackId;
3542
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
3918
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react22.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
3543
3919
  const currentText = value !== void 0 ? String(value) : uncontrolledValue;
3544
3920
  const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
3545
3921
  const hintId = `${textAreaId}-hint`;
@@ -3600,26 +3976,26 @@ function TypographyContent({
3600
3976
  className = "",
3601
3977
  ...props
3602
3978
  }) {
3603
- const contentRef = (0, import_react21.useRef)(null);
3604
- const editRef = (0, import_react21.useRef)(null);
3605
- const timer = (0, import_react21.useRef)();
3606
- const [localText, setLocalText] = (0, import_react21.useState)();
3607
- const [draft, setDraft] = (0, import_react21.useState)("");
3608
- const [editing, setEditing] = (0, import_react21.useState)(false);
3609
- const [copied, setCopied] = (0, import_react21.useState)(false);
3610
- const [copyError, setCopyError] = (0, import_react21.useState)(false);
3611
- const [expanded, setExpanded] = (0, import_react21.useState)(false);
3612
- const [overflow, setOverflow] = (0, import_react21.useState)(false);
3979
+ const contentRef = (0, import_react23.useRef)(null);
3980
+ const editRef = (0, import_react23.useRef)(null);
3981
+ const timer = (0, import_react23.useRef)();
3982
+ const [localText, setLocalText] = (0, import_react23.useState)();
3983
+ const [draft, setDraft] = (0, import_react23.useState)("");
3984
+ const [editing, setEditing] = (0, import_react23.useState)(false);
3985
+ const [copied, setCopied] = (0, import_react23.useState)(false);
3986
+ const [copyError, setCopyError] = (0, import_react23.useState)(false);
3987
+ const [expanded, setExpanded] = (0, import_react23.useState)(false);
3988
+ const [overflow, setOverflow] = (0, import_react23.useState)(false);
3613
3989
  const editConfig = typeof editable === "object" ? editable : void 0;
3614
3990
  const content = editConfig?.text ?? localText ?? children;
3615
3991
  const requestedRows = typeof ellipsis === "object" ? ellipsis.rows ?? 1 : 1;
3616
3992
  const rows = Number.isFinite(requestedRows) ? Math.max(1, Math.floor(requestedRows)) : 1;
3617
3993
  const expandable = typeof ellipsis === "object" && ellipsis.expandable;
3618
- (0, import_react21.useEffect)(() => {
3994
+ (0, import_react23.useEffect)(() => {
3619
3995
  setLocalText(void 0);
3620
3996
  }, [children]);
3621
- (0, import_react21.useEffect)(() => () => clearTimeout(timer.current), []);
3622
- (0, import_react21.useLayoutEffect)(() => {
3997
+ (0, import_react23.useEffect)(() => () => clearTimeout(timer.current), []);
3998
+ (0, import_react23.useLayoutEffect)(() => {
3623
3999
  const element = contentRef.current;
3624
4000
  if (!element || !ellipsis || editing || expanded) return;
3625
4001
  const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
@@ -3728,10 +4104,10 @@ function TypographyRoot({ className = "", ...props }) {
3728
4104
  var Typography = Object.assign(TypographyRoot, { Title, Text, Paragraph, Link });
3729
4105
 
3730
4106
  // src/components/FloatButton.tsx
3731
- var import_react22 = require("react");
4107
+ var import_react24 = require("react");
3732
4108
  var import_jsx_runtime25 = require("react/jsx-runtime");
3733
- var GroupShape = (0, import_react22.createContext)(void 0);
3734
- var FloatButtonRoot = (0, import_react22.forwardRef)(function FloatButton({
4109
+ var GroupShape = (0, import_react24.createContext)(void 0);
4110
+ var FloatButtonRoot = (0, import_react24.forwardRef)(function FloatButton({
3735
4111
  icon,
3736
4112
  description,
3737
4113
  tooltip,
@@ -3744,7 +4120,7 @@ var FloatButtonRoot = (0, import_react22.forwardRef)(function FloatButton({
3744
4120
  children,
3745
4121
  ...props
3746
4122
  }, ref) {
3747
- const groupShape = (0, import_react22.useContext)(GroupShape);
4123
+ const groupShape = (0, import_react24.useContext)(GroupShape);
3748
4124
  const label = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof description === "string" ? description : "\u60AC\u6D6E\u64CD\u4F5C");
3749
4125
  const button = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3750
4126
  "button",
@@ -3782,10 +4158,10 @@ function FloatButtonGroup({
3782
4158
  ...props
3783
4159
  }) {
3784
4160
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
3785
- const rootRef = (0, import_react22.useRef)(null);
3786
- const triggerRef = (0, import_react22.useRef)(null);
3787
- const id = (0, import_react22.useId)();
3788
- (0, import_react22.useEffect)(() => {
4161
+ const rootRef = (0, import_react24.useRef)(null);
4162
+ const triggerRef = (0, import_react24.useRef)(null);
4163
+ const id = (0, import_react24.useId)();
4164
+ (0, import_react24.useEffect)(() => {
3789
4165
  if (!trigger || !visible) return;
3790
4166
  const close = (event) => {
3791
4167
  if (!rootRef.current?.contains(event.target)) setVisible(false);
@@ -3839,8 +4215,8 @@ function FloatButtonGroup({
3839
4215
  ) });
3840
4216
  }
3841
4217
  function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth", onClick, icon, tooltip = "\u8FD4\u56DE\u9876\u90E8", ...props }) {
3842
- const [visible, setVisible] = (0, import_react22.useState)(false);
3843
- (0, import_react22.useEffect)(() => {
4218
+ const [visible, setVisible] = (0, import_react24.useState)(false);
4219
+ (0, import_react24.useEffect)(() => {
3844
4220
  const element = target ? target() : window;
3845
4221
  if (!element) return;
3846
4222
  const update = () => setVisible((element === window ? window.scrollY : element.scrollTop) >= visibilityHeight);
package/dist/core.css CHANGED
@@ -1788,7 +1788,7 @@ fieldset:disabled .sia-input-number__floating-placeholder {
1788
1788
  display: flex;
1789
1789
  flex-direction: column;
1790
1790
  width: max-content;
1791
- min-width: 90px;
1791
+ min-width: min(max(90px, var(--sia-popup-anchor-width, 0px)), calc(100vw - 16px));
1792
1792
  padding: 4px;
1793
1793
  background: var(--sia-color-surface);
1794
1794
  border: 1px solid var(--sia-color-border);
@@ -4868,6 +4868,9 @@ fieldset:disabled .sia-input-number__floating-placeholder {
4868
4868
  transition: none;
4869
4869
  }
4870
4870
  }
4871
+ .sia-table-settings__loading {
4872
+ min-height: 160px;
4873
+ }
4871
4874
 
4872
4875
  /* src/components-extra.css */
4873
4876
  .sia-flex {