@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/{chunk-25BU7YTB.js → chunk-G47MREYI.js} +1 -1
- package/dist/{chunk-E7F47Z2C.js → chunk-KJYKC5IV.js} +1 -1
- package/dist/{chunk-R3TYVU53.js → chunk-VXSG4EAO.js} +384 -6
- package/dist/core.cjs +432 -56
- package/dist/core.css +4 -1
- package/dist/core.js +2 -2
- package/dist/index.cjs +3265 -2457
- package/dist/index.css +4 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1168 -734
- package/dist/select-date-range.cjs +400 -24
- package/dist/select-date-range.js +2 -2
- package/package.json +1 -1
|
@@ -1789,7 +1789,7 @@ function DateRangePicker({
|
|
|
1789
1789
|
})(DatePicker || (DatePicker = {}));
|
|
1790
1790
|
|
|
1791
1791
|
// src/components/Select.tsx
|
|
1792
|
-
var
|
|
1792
|
+
var import_react16 = require("react");
|
|
1793
1793
|
|
|
1794
1794
|
// src/components/Modal.tsx
|
|
1795
1795
|
var import_react8 = require("react");
|
|
@@ -2090,7 +2090,7 @@ function openModal(config) {
|
|
|
2090
2090
|
let currentOpen = true;
|
|
2091
2091
|
let destroyed = false;
|
|
2092
2092
|
let cleanupTimer;
|
|
2093
|
-
function
|
|
2093
|
+
function cleanup2() {
|
|
2094
2094
|
if (destroyed) return;
|
|
2095
2095
|
destroyed = true;
|
|
2096
2096
|
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
@@ -2102,7 +2102,7 @@ function openModal(config) {
|
|
|
2102
2102
|
if (destroyed || !currentOpen) return;
|
|
2103
2103
|
currentOpen = false;
|
|
2104
2104
|
render();
|
|
2105
|
-
cleanupTimer = window.setTimeout(
|
|
2105
|
+
cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
|
|
2106
2106
|
}
|
|
2107
2107
|
function render() {
|
|
2108
2108
|
root.render(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
@@ -2738,13 +2738,388 @@ function OverflowTags({ items, maxCount, className = "", tagClassName, restClass
|
|
|
2738
2738
|
] });
|
|
2739
2739
|
}
|
|
2740
2740
|
|
|
2741
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
2742
|
+
var import_react15 = require("react");
|
|
2743
|
+
|
|
2744
|
+
// src/components/useScrollbarProximity.ts
|
|
2745
|
+
var import_react14 = require("react");
|
|
2746
|
+
var users = 0;
|
|
2747
|
+
var cleanup;
|
|
2748
|
+
function useScrollbarProximity() {
|
|
2749
|
+
(0, import_react14.useEffect)(() => {
|
|
2750
|
+
if (users++ === 0) {
|
|
2751
|
+
let frame = 0;
|
|
2752
|
+
let x = -Infinity;
|
|
2753
|
+
let y = -Infinity;
|
|
2754
|
+
const nearby = /* @__PURE__ */ new Set();
|
|
2755
|
+
const clear = () => {
|
|
2756
|
+
nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
|
|
2757
|
+
nearby.clear();
|
|
2758
|
+
};
|
|
2759
|
+
const update = () => {
|
|
2760
|
+
frame = 0;
|
|
2761
|
+
const next = /* @__PURE__ */ new Set();
|
|
2762
|
+
document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
|
|
2763
|
+
const rect = track.getBoundingClientRect();
|
|
2764
|
+
const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
|
|
2765
|
+
if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
|
|
2766
|
+
next.add(track);
|
|
2767
|
+
if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
|
|
2768
|
+
}
|
|
2769
|
+
});
|
|
2770
|
+
nearby.forEach((track) => {
|
|
2771
|
+
if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
|
|
2772
|
+
});
|
|
2773
|
+
nearby.clear();
|
|
2774
|
+
next.forEach((track) => nearby.add(track));
|
|
2775
|
+
};
|
|
2776
|
+
const move = (event) => {
|
|
2777
|
+
if (event.pointerType === "touch") return;
|
|
2778
|
+
x = event.clientX;
|
|
2779
|
+
y = event.clientY;
|
|
2780
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
2781
|
+
};
|
|
2782
|
+
const leave = () => {
|
|
2783
|
+
x = y = -Infinity;
|
|
2784
|
+
clear();
|
|
2785
|
+
};
|
|
2786
|
+
document.addEventListener("pointermove", move, { passive: true });
|
|
2787
|
+
document.documentElement.addEventListener("pointerleave", leave);
|
|
2788
|
+
window.addEventListener("blur", leave);
|
|
2789
|
+
cleanup = () => {
|
|
2790
|
+
if (frame) cancelAnimationFrame(frame);
|
|
2791
|
+
document.removeEventListener("pointermove", move);
|
|
2792
|
+
document.documentElement.removeEventListener("pointerleave", leave);
|
|
2793
|
+
window.removeEventListener("blur", leave);
|
|
2794
|
+
clear();
|
|
2795
|
+
};
|
|
2796
|
+
}
|
|
2797
|
+
return () => {
|
|
2798
|
+
if (--users === 0) {
|
|
2799
|
+
cleanup?.();
|
|
2800
|
+
cleanup = void 0;
|
|
2801
|
+
}
|
|
2802
|
+
};
|
|
2803
|
+
}, []);
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
2807
|
+
var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
2808
|
+
var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
|
|
2809
|
+
function isRootScroller(target) {
|
|
2810
|
+
return target === document.scrollingElement || target === document.documentElement;
|
|
2811
|
+
}
|
|
2812
|
+
function canScroll(target, axis) {
|
|
2813
|
+
if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
|
|
2814
|
+
if (isRootScroller(target)) {
|
|
2815
|
+
return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
2816
|
+
}
|
|
2817
|
+
const style = getComputedStyle(target);
|
|
2818
|
+
const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
|
|
2819
|
+
const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
2820
|
+
return hasOverflow && scrollableOverflow.has(overflow);
|
|
2821
|
+
}
|
|
2822
|
+
function visibleRect(target) {
|
|
2823
|
+
if (isRootScroller(target)) {
|
|
2824
|
+
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
2825
|
+
}
|
|
2826
|
+
const ownRect = target.getBoundingClientRect();
|
|
2827
|
+
let top = Math.max(0, ownRect.top);
|
|
2828
|
+
let right = Math.min(window.innerWidth, ownRect.right);
|
|
2829
|
+
let bottom = Math.min(window.innerHeight, ownRect.bottom);
|
|
2830
|
+
let left = Math.max(0, ownRect.left);
|
|
2831
|
+
let parent = target.parentElement;
|
|
2832
|
+
while (parent && parent !== document.body && parent !== document.documentElement) {
|
|
2833
|
+
const style = getComputedStyle(parent);
|
|
2834
|
+
const clipX = clippingOverflow.has(style.overflowX);
|
|
2835
|
+
const clipY = clippingOverflow.has(style.overflowY);
|
|
2836
|
+
if (clipX || clipY) {
|
|
2837
|
+
const rect = parent.getBoundingClientRect();
|
|
2838
|
+
if (clipX) {
|
|
2839
|
+
left = Math.max(left, rect.left);
|
|
2840
|
+
right = Math.min(right, rect.right);
|
|
2841
|
+
}
|
|
2842
|
+
if (clipY) {
|
|
2843
|
+
top = Math.max(top, rect.top);
|
|
2844
|
+
bottom = Math.min(bottom, rect.bottom);
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
parent = parent.parentElement;
|
|
2848
|
+
}
|
|
2849
|
+
return {
|
|
2850
|
+
top,
|
|
2851
|
+
right,
|
|
2852
|
+
bottom,
|
|
2853
|
+
left,
|
|
2854
|
+
width: Math.max(0, right - left),
|
|
2855
|
+
height: Math.max(0, bottom - top)
|
|
2856
|
+
};
|
|
2857
|
+
}
|
|
2858
|
+
function createTrack(axis) {
|
|
2859
|
+
const track = document.createElement("div");
|
|
2860
|
+
const thumb = document.createElement("div");
|
|
2861
|
+
track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
|
|
2862
|
+
thumb.className = "sia-floating-scrollbar__thumb";
|
|
2863
|
+
track.dataset.axis = axis;
|
|
2864
|
+
track.setAttribute("aria-hidden", "true");
|
|
2865
|
+
track.append(thumb);
|
|
2866
|
+
return { track, thumb };
|
|
2867
|
+
}
|
|
2868
|
+
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
2869
|
+
useScrollbarProximity();
|
|
2870
|
+
(0, import_react15.useEffect)(() => {
|
|
2871
|
+
if (disabled) return;
|
|
2872
|
+
const layer = document.createElement("div");
|
|
2873
|
+
layer.className = "sia-floating-scrollbar-layer";
|
|
2874
|
+
layer.setAttribute("aria-hidden", "true");
|
|
2875
|
+
document.body.append(layer);
|
|
2876
|
+
const entries = /* @__PURE__ */ new Map();
|
|
2877
|
+
let scanFrame = 0;
|
|
2878
|
+
let updateFrame = 0;
|
|
2879
|
+
const setEntryVisible = (entry, visible) => {
|
|
2880
|
+
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
2881
|
+
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
2882
|
+
};
|
|
2883
|
+
const showEntry = (entry) => {
|
|
2884
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
2885
|
+
entry.hideTimer = null;
|
|
2886
|
+
setEntryVisible(entry, true);
|
|
2887
|
+
};
|
|
2888
|
+
const scheduleHide = (entry, delay = 500) => {
|
|
2889
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
2890
|
+
entry.hideTimer = window.setTimeout(() => {
|
|
2891
|
+
entry.hideTimer = null;
|
|
2892
|
+
if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
|
|
2893
|
+
}, delay);
|
|
2894
|
+
};
|
|
2895
|
+
const updateEntry = (entry) => {
|
|
2896
|
+
const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
|
|
2897
|
+
const hasHorizontal = canScroll(target, "horizontal");
|
|
2898
|
+
const hasVertical = canScroll(target, "vertical");
|
|
2899
|
+
const rect = visibleRect(target);
|
|
2900
|
+
const thickness = 10;
|
|
2901
|
+
horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
|
|
2902
|
+
verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
|
|
2903
|
+
if (!horizontalTrack.hidden) {
|
|
2904
|
+
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
2905
|
+
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
2906
|
+
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
2907
|
+
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
2908
|
+
horizontalTrack.style.left = `${rect.left}px`;
|
|
2909
|
+
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
2910
|
+
horizontalTrack.style.width = `${trackWidth}px`;
|
|
2911
|
+
horizontalTrack.style.height = `${thickness}px`;
|
|
2912
|
+
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
2913
|
+
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
2914
|
+
}
|
|
2915
|
+
if (!verticalTrack.hidden) {
|
|
2916
|
+
const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
|
|
2917
|
+
const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
|
|
2918
|
+
const travel = Math.max(0, trackHeight - thumbHeight);
|
|
2919
|
+
const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
|
|
2920
|
+
verticalTrack.style.left = `${rect.right - thickness}px`;
|
|
2921
|
+
verticalTrack.style.top = `${rect.top}px`;
|
|
2922
|
+
verticalTrack.style.width = `${thickness}px`;
|
|
2923
|
+
verticalTrack.style.height = `${trackHeight}px`;
|
|
2924
|
+
verticalThumb.style.height = `${thumbHeight}px`;
|
|
2925
|
+
verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
|
|
2926
|
+
}
|
|
2927
|
+
};
|
|
2928
|
+
const scheduleUpdateAll = () => {
|
|
2929
|
+
if (updateFrame) return;
|
|
2930
|
+
updateFrame = window.requestAnimationFrame(() => {
|
|
2931
|
+
updateFrame = 0;
|
|
2932
|
+
entries.forEach(updateEntry);
|
|
2933
|
+
});
|
|
2934
|
+
};
|
|
2935
|
+
const bindTrackDrag = (entry, axis, track, thumb) => {
|
|
2936
|
+
const target = entry.target;
|
|
2937
|
+
const onTrackPointerEnter = () => {
|
|
2938
|
+
entry.hoveringTrack = true;
|
|
2939
|
+
showEntry(entry);
|
|
2940
|
+
};
|
|
2941
|
+
const onTrackPointerLeave = () => {
|
|
2942
|
+
entry.hoveringTrack = false;
|
|
2943
|
+
scheduleHide(entry);
|
|
2944
|
+
};
|
|
2945
|
+
const onTrackPointerDown = (event) => {
|
|
2946
|
+
if (event.target === thumb || event.button !== 0) return;
|
|
2947
|
+
event.preventDefault();
|
|
2948
|
+
event.stopPropagation();
|
|
2949
|
+
const trackRect = track.getBoundingClientRect();
|
|
2950
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
2951
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
2952
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
2953
|
+
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
2954
|
+
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
2955
|
+
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
2956
|
+
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
2957
|
+
};
|
|
2958
|
+
const onThumbPointerDown = (event) => {
|
|
2959
|
+
if (event.button !== 0) return;
|
|
2960
|
+
event.preventDefault();
|
|
2961
|
+
event.stopPropagation();
|
|
2962
|
+
entry.dragging = true;
|
|
2963
|
+
showEntry(entry);
|
|
2964
|
+
thumb.setPointerCapture(event.pointerId);
|
|
2965
|
+
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
2966
|
+
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
2967
|
+
const trackRect = track.getBoundingClientRect();
|
|
2968
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
2969
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
2970
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
2971
|
+
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
2972
|
+
const travel = Math.max(1, trackLength - thumbLength);
|
|
2973
|
+
const onPointerMove = (moveEvent) => {
|
|
2974
|
+
if (moveEvent.pointerId !== event.pointerId) return;
|
|
2975
|
+
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
2976
|
+
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
2977
|
+
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
2978
|
+
else target.scrollLeft = nextScroll;
|
|
2979
|
+
};
|
|
2980
|
+
const onPointerUp = (upEvent) => {
|
|
2981
|
+
if (upEvent.pointerId !== event.pointerId) return;
|
|
2982
|
+
entry.dragging = false;
|
|
2983
|
+
thumb.releasePointerCapture(event.pointerId);
|
|
2984
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
2985
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
2986
|
+
window.removeEventListener("pointercancel", onPointerUp);
|
|
2987
|
+
scheduleHide(entry);
|
|
2988
|
+
};
|
|
2989
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
2990
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
2991
|
+
window.addEventListener("pointercancel", onPointerUp);
|
|
2992
|
+
};
|
|
2993
|
+
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
2994
|
+
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
2995
|
+
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
2996
|
+
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
2997
|
+
return () => {
|
|
2998
|
+
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
2999
|
+
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
3000
|
+
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
3001
|
+
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
3002
|
+
};
|
|
3003
|
+
};
|
|
3004
|
+
const resizeObserver = new ResizeObserver((observedEntries) => {
|
|
3005
|
+
observedEntries.forEach(({ target }) => {
|
|
3006
|
+
const entry = entries.get(target);
|
|
3007
|
+
if (entry) updateEntry(entry);
|
|
3008
|
+
});
|
|
3009
|
+
});
|
|
3010
|
+
const addTarget = (target) => {
|
|
3011
|
+
if (entries.has(target)) return;
|
|
3012
|
+
const horizontal = createTrack("horizontal");
|
|
3013
|
+
const vertical = createTrack("vertical");
|
|
3014
|
+
layer.append(horizontal.track, vertical.track);
|
|
3015
|
+
const onPointerEnter = () => {
|
|
3016
|
+
const entry2 = entries.get(target);
|
|
3017
|
+
if (!entry2) return;
|
|
3018
|
+
entry2.hoveringTarget = true;
|
|
3019
|
+
showEntry(entry2);
|
|
3020
|
+
};
|
|
3021
|
+
const onPointerLeave = () => {
|
|
3022
|
+
const entry2 = entries.get(target);
|
|
3023
|
+
if (!entry2) return;
|
|
3024
|
+
entry2.hoveringTarget = false;
|
|
3025
|
+
scheduleHide(entry2);
|
|
3026
|
+
};
|
|
3027
|
+
const onScroll = () => {
|
|
3028
|
+
const entry2 = entries.get(target);
|
|
3029
|
+
if (!entry2) return;
|
|
3030
|
+
updateEntry(entry2);
|
|
3031
|
+
showEntry(entry2);
|
|
3032
|
+
scheduleHide(entry2, 700);
|
|
3033
|
+
};
|
|
3034
|
+
target.addEventListener("pointerenter", onPointerEnter);
|
|
3035
|
+
target.addEventListener("pointerleave", onPointerLeave);
|
|
3036
|
+
target.addEventListener("scroll", onScroll, { passive: true });
|
|
3037
|
+
const entry = {
|
|
3038
|
+
target,
|
|
3039
|
+
horizontalTrack: horizontal.track,
|
|
3040
|
+
horizontalThumb: horizontal.thumb,
|
|
3041
|
+
verticalTrack: vertical.track,
|
|
3042
|
+
verticalThumb: vertical.thumb,
|
|
3043
|
+
hideTimer: null,
|
|
3044
|
+
hoveringTarget: target.matches(":hover"),
|
|
3045
|
+
hoveringTrack: false,
|
|
3046
|
+
dragging: false,
|
|
3047
|
+
cleanup: () => void 0
|
|
3048
|
+
};
|
|
3049
|
+
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
3050
|
+
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
3051
|
+
entry.cleanup = () => {
|
|
3052
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3053
|
+
cleanupHorizontal();
|
|
3054
|
+
cleanupVertical();
|
|
3055
|
+
target.removeEventListener("pointerenter", onPointerEnter);
|
|
3056
|
+
target.removeEventListener("pointerleave", onPointerLeave);
|
|
3057
|
+
target.removeEventListener("scroll", onScroll);
|
|
3058
|
+
resizeObserver.unobserve(target);
|
|
3059
|
+
target.removeAttribute("data-sia-floating-scrollbar");
|
|
3060
|
+
horizontal.track.remove();
|
|
3061
|
+
vertical.track.remove();
|
|
3062
|
+
};
|
|
3063
|
+
entries.set(target, entry);
|
|
3064
|
+
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
3065
|
+
resizeObserver.observe(target);
|
|
3066
|
+
updateEntry(entry);
|
|
3067
|
+
if (entry.hoveringTarget) showEntry(entry);
|
|
3068
|
+
};
|
|
3069
|
+
const removeTarget = (target) => {
|
|
3070
|
+
const entry = entries.get(target);
|
|
3071
|
+
if (!entry) return;
|
|
3072
|
+
entry.cleanup();
|
|
3073
|
+
entries.delete(target);
|
|
3074
|
+
};
|
|
3075
|
+
const scanTargets = () => {
|
|
3076
|
+
scanFrame = 0;
|
|
3077
|
+
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
3078
|
+
const nextTargets = /* @__PURE__ */ new Set();
|
|
3079
|
+
candidates.forEach((target) => {
|
|
3080
|
+
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
3081
|
+
nextTargets.add(target);
|
|
3082
|
+
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
3083
|
+
}
|
|
3084
|
+
});
|
|
3085
|
+
entries.forEach((_entry, target) => {
|
|
3086
|
+
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
3087
|
+
else updateEntry(_entry);
|
|
3088
|
+
});
|
|
3089
|
+
};
|
|
3090
|
+
const scheduleScan = () => {
|
|
3091
|
+
if (scanFrame) return;
|
|
3092
|
+
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
3093
|
+
};
|
|
3094
|
+
const mutationObserver = new MutationObserver((mutations) => {
|
|
3095
|
+
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
3096
|
+
});
|
|
3097
|
+
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
3098
|
+
window.addEventListener("resize", scheduleScan);
|
|
3099
|
+
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
3100
|
+
scheduleScan();
|
|
3101
|
+
return () => {
|
|
3102
|
+
mutationObserver.disconnect();
|
|
3103
|
+
resizeObserver.disconnect();
|
|
3104
|
+
window.removeEventListener("resize", scheduleScan);
|
|
3105
|
+
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
3106
|
+
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
3107
|
+
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
3108
|
+
entries.forEach((entry) => entry.cleanup());
|
|
3109
|
+
entries.clear();
|
|
3110
|
+
layer.remove();
|
|
3111
|
+
};
|
|
3112
|
+
}, [disabled, targetRef]);
|
|
3113
|
+
return null;
|
|
3114
|
+
}
|
|
3115
|
+
|
|
2741
3116
|
// src/components/Select.tsx
|
|
2742
3117
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2743
3118
|
function defaultFilterOption(query, option) {
|
|
2744
3119
|
const keyword = query.toLowerCase();
|
|
2745
3120
|
return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
|
|
2746
3121
|
}
|
|
2747
|
-
var Select = (0,
|
|
3122
|
+
var Select = (0, import_react16.forwardRef)(function Select2({
|
|
2748
3123
|
options,
|
|
2749
3124
|
mode = "single",
|
|
2750
3125
|
popupMode = "dropdown",
|
|
@@ -2781,20 +3156,20 @@ var Select = (0, import_react14.forwardRef)(function Select2({
|
|
|
2781
3156
|
...props
|
|
2782
3157
|
}, forwardedRef) {
|
|
2783
3158
|
const size = useControlSize(sizeProp);
|
|
2784
|
-
const fallbackId = (0,
|
|
3159
|
+
const fallbackId = (0, import_react16.useId)();
|
|
2785
3160
|
const selectId = id ?? fallbackId;
|
|
2786
3161
|
const listboxId = `${selectId}-listbox`;
|
|
2787
|
-
const rootRef = (0,
|
|
2788
|
-
const popupRef = (0,
|
|
2789
|
-
const searchRef = (0,
|
|
2790
|
-
const listRef = (0,
|
|
2791
|
-
const [open, setOpen] = (0,
|
|
2792
|
-
const [modalValues, setModalValues] = (0,
|
|
2793
|
-
const [selectedOnly, setSelectedOnly] = (0,
|
|
2794
|
-
const [query, setQuery] = (0,
|
|
2795
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
2796
|
-
const [scrollTop, setScrollTop] = (0,
|
|
2797
|
-
const deferredQuery = (0,
|
|
3162
|
+
const rootRef = (0, import_react16.useRef)(null);
|
|
3163
|
+
const popupRef = (0, import_react16.useRef)(null);
|
|
3164
|
+
const searchRef = (0, import_react16.useRef)(null);
|
|
3165
|
+
const listRef = (0, import_react16.useRef)(null);
|
|
3166
|
+
const [open, setOpen] = (0, import_react16.useState)(false);
|
|
3167
|
+
const [modalValues, setModalValues] = (0, import_react16.useState)([]);
|
|
3168
|
+
const [selectedOnly, setSelectedOnly] = (0, import_react16.useState)(false);
|
|
3169
|
+
const [query, setQuery] = (0, import_react16.useState)("");
|
|
3170
|
+
const [activeIndex, setActiveIndex] = (0, import_react16.useState)(-1);
|
|
3171
|
+
const [scrollTop, setScrollTop] = (0, import_react16.useState)(0);
|
|
3172
|
+
const deferredQuery = (0, import_react16.useDeferredValue)(query.trim());
|
|
2798
3173
|
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
2799
3174
|
const [currentValue, setCurrentValue] = useControllableState({
|
|
2800
3175
|
value,
|
|
@@ -2809,19 +3184,19 @@ var Select = (0, import_react14.forwardRef)(function Select2({
|
|
|
2809
3184
|
}
|
|
2810
3185
|
}
|
|
2811
3186
|
});
|
|
2812
|
-
const selectedValues = (0,
|
|
3187
|
+
const selectedValues = (0, import_react16.useMemo)(() => {
|
|
2813
3188
|
if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
|
|
2814
3189
|
return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
|
|
2815
3190
|
}, [currentValue, mode]);
|
|
2816
|
-
const selectedValueSet = (0,
|
|
2817
|
-
const availableOptions = (0,
|
|
3191
|
+
const selectedValueSet = (0, import_react16.useMemo)(() => new Set(selectedValues), [selectedValues]);
|
|
3192
|
+
const availableOptions = (0, import_react16.useMemo)(() => {
|
|
2818
3193
|
if (!allowInput) return options;
|
|
2819
3194
|
const optionValueSet = new Set(options.map((option) => option.value));
|
|
2820
3195
|
const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
|
|
2821
3196
|
return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
|
|
2822
3197
|
}, [allowInput, options, selectedValues]);
|
|
2823
|
-
const selectedOptions = (0,
|
|
2824
|
-
const filteredOptions = (0,
|
|
3198
|
+
const selectedOptions = (0, import_react16.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
|
|
3199
|
+
const filteredOptions = (0, import_react16.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
|
|
2825
3200
|
const inputValue = query.trim();
|
|
2826
3201
|
const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
|
|
2827
3202
|
const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
|
|
@@ -2835,7 +3210,7 @@ var Select = (0, import_react14.forwardRef)(function Select2({
|
|
|
2835
3210
|
const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
|
|
2836
3211
|
const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
|
|
2837
3212
|
const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
|
|
2838
|
-
(0,
|
|
3213
|
+
(0, import_react16.useEffect)(() => {
|
|
2839
3214
|
if (!open || popupMode === "modal") return void 0;
|
|
2840
3215
|
function closeFromOutside(event) {
|
|
2841
3216
|
const target = event.target;
|
|
@@ -2844,10 +3219,10 @@ var Select = (0, import_react14.forwardRef)(function Select2({
|
|
|
2844
3219
|
document.addEventListener("mousedown", closeFromOutside);
|
|
2845
3220
|
return () => document.removeEventListener("mousedown", closeFromOutside);
|
|
2846
3221
|
}, [open, popupMode]);
|
|
2847
|
-
(0,
|
|
3222
|
+
(0, import_react16.useEffect)(() => {
|
|
2848
3223
|
if (open && (showSearch || allowInput)) searchRef.current?.focus();
|
|
2849
3224
|
}, [allowInput, open, showSearch]);
|
|
2850
|
-
(0,
|
|
3225
|
+
(0, import_react16.useEffect)(() => {
|
|
2851
3226
|
if (disabled || loading) closeDropdown();
|
|
2852
3227
|
}, [disabled, loading]);
|
|
2853
3228
|
function firstEnabledIndex() {
|
|
@@ -3034,6 +3409,7 @@ var Select = (0, import_react14.forwardRef)(function Select2({
|
|
|
3034
3409
|
),
|
|
3035
3410
|
allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
3036
3411
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
|
|
3412
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FloatingScrollbarProvider, { targetRef: listRef }),
|
|
3037
3413
|
showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "sia-select__search", children: [
|
|
3038
3414
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "search", size: 15 }),
|
|
3039
3415
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
|