@sia.soul/sia-react-ui 0.1.39 → 0.1.41
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-LRGD2QDA.js → chunk-3Q3S6CDZ.js} +975 -929
- package/dist/{chunk-WR7XTQRU.js → chunk-IPDCEXQO.js} +149 -64
- package/dist/{chunk-GLS4WVIZ.js → chunk-LWVZEUGJ.js} +88 -89
- package/dist/{core-D4opRFkZ.d.cts → core-C2IieVNm.d.cts} +25 -12
- package/dist/{core-VNY_7WRq.d.ts → core-ZmKnvCFV.d.ts} +25 -12
- package/dist/core.cjs +1071 -978
- package/dist/core.css +64 -21
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +2 -2
- package/dist/index.cjs +751 -620
- package/dist/index.css +64 -21
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/{select-date-range-CtA-B8DB.d.cts → select-date-range-2galnCvZ.d.cts} +10 -5
- package/dist/{select-date-range-D9W_mmMq.d.ts → select-date-range-Dtj6XF9I.d.ts} +10 -5
- package/dist/select-date-range.cjs +164 -119
- package/dist/select-date-range.d.cts +1 -1
- package/dist/select-date-range.d.ts +1 -1
- package/dist/select-date-range.js +2 -2
- package/package.json +1 -1
|
@@ -15,715 +15,386 @@ import {
|
|
|
15
15
|
withTitleTooltip
|
|
16
16
|
} from "./chunk-H7IAG72O.js";
|
|
17
17
|
|
|
18
|
-
// src/components/
|
|
19
|
-
import { useEffect
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
// src/components/Checkbox.tsx
|
|
19
|
+
import { createContext, forwardRef, useContext, useEffect, useId, useMemo, useRef } from "react";
|
|
20
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
+
var CheckboxGroupContext = createContext(null);
|
|
22
|
+
var CheckboxRoot = forwardRef(function Checkbox({ value, size: sizeProp, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
|
|
23
|
+
const size = useControlSize(sizeProp);
|
|
24
|
+
const group = useContext(CheckboxGroupContext);
|
|
25
|
+
const localRef = useRef(null);
|
|
26
|
+
const fallbackId = useId();
|
|
27
|
+
const grouped = group !== null && value !== void 0;
|
|
28
|
+
const currentChecked = grouped ? group.values.includes(value) : checked;
|
|
26
29
|
useEffect(() => {
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
30
|
+
if (localRef.current) localRef.current.indeterminate = indeterminate;
|
|
31
|
+
}, [indeterminate]);
|
|
32
|
+
function setRef(node) {
|
|
33
|
+
localRef.current = node;
|
|
34
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
35
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
36
|
+
}
|
|
37
|
+
return /* @__PURE__ */ jsxs("label", { className: `sia-checkbox sia-checkbox--${size}${disabled || group?.disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
|
|
38
|
+
/* @__PURE__ */ jsx(
|
|
39
|
+
"input",
|
|
40
|
+
{
|
|
41
|
+
...withTitleTooltip(props),
|
|
42
|
+
ref: setRef,
|
|
43
|
+
id: props.id ?? fallbackId,
|
|
44
|
+
className: "sia-checkbox__input",
|
|
45
|
+
type: "checkbox",
|
|
46
|
+
name: group?.name ?? props.name,
|
|
47
|
+
disabled: disabled || group?.disabled,
|
|
48
|
+
checked: currentChecked,
|
|
49
|
+
defaultChecked: grouped ? void 0 : defaultChecked,
|
|
50
|
+
"aria-checked": indeterminate ? "mixed" : currentChecked,
|
|
51
|
+
onChange: (event) => {
|
|
52
|
+
if (grouped) group.toggle(value, event.currentTarget.checked);
|
|
53
|
+
onChange?.(event.currentTarget.checked, event);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
/* @__PURE__ */ jsx("span", { className: "sia-checkbox__control", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", {}) }),
|
|
58
|
+
children !== void 0 ? /* @__PURE__ */ jsx("span", { className: "sia-checkbox__label", children }) : null
|
|
59
|
+
] });
|
|
60
|
+
});
|
|
61
|
+
function CheckboxGroup({
|
|
62
|
+
size: sizeProp,
|
|
63
|
+
columns,
|
|
64
|
+
direction = "horizontal",
|
|
65
|
+
gap,
|
|
66
|
+
value,
|
|
67
|
+
defaultValue = [],
|
|
68
|
+
options,
|
|
69
|
+
disabled,
|
|
70
|
+
name,
|
|
71
|
+
className = "",
|
|
72
|
+
children,
|
|
73
|
+
onChange
|
|
74
|
+
}) {
|
|
75
|
+
const size = useControlSize(sizeProp);
|
|
76
|
+
const gridColumns = columns !== void 0 && Number.isInteger(columns) && columns > 0 ? columns : void 0;
|
|
77
|
+
const layoutStyle = {
|
|
78
|
+
gridTemplateColumns: gridColumns ? `repeat(${gridColumns}, minmax(0, 1fr))` : void 0,
|
|
79
|
+
gap: gap === void 0 ? void 0 : typeof gap === "number" ? Math.max(0, gap) : `${Math.max(0, gap[0])}px ${Math.max(0, gap[1])}px`
|
|
80
|
+
};
|
|
81
|
+
const [values, setValues] = useControllableState({ value, defaultValue, onChange });
|
|
82
|
+
const context = useMemo(() => ({
|
|
83
|
+
values,
|
|
84
|
+
disabled,
|
|
85
|
+
name,
|
|
86
|
+
toggle(optionValue, checked) {
|
|
87
|
+
const next = checked ? values.includes(optionValue) ? values : [...values, optionValue] : values.filter((item) => item !== optionValue);
|
|
88
|
+
setValues(next);
|
|
73
89
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
90
|
+
}), [disabled, name, setValues, values]);
|
|
91
|
+
return /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx(CheckboxGroupContext.Provider, { value: context, children: /* @__PURE__ */ jsxs("div", { className: `sia-checkbox-group${gridColumns ? " sia-checkbox-group--grid" : direction === "vertical" ? " sia-checkbox-group--vertical" : ""} ${className}`.trim(), style: layoutStyle, role: "group", children: [
|
|
92
|
+
options?.map((option) => {
|
|
93
|
+
const normalized = typeof option === "object" ? option : { label: String(option), value: option };
|
|
94
|
+
return /* @__PURE__ */ jsx(CheckboxRoot, { value: normalized.value, disabled: normalized.disabled, children: normalized.label }, normalized.value);
|
|
95
|
+
}),
|
|
96
|
+
children
|
|
97
|
+
] }) }) });
|
|
98
|
+
}
|
|
99
|
+
var Checkbox2 = Object.assign(CheckboxRoot, {
|
|
100
|
+
/** 组合多个子项并统一管理布局或选择状态。 */
|
|
101
|
+
Group: CheckboxGroup
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// src/components/treeCheckState.ts
|
|
105
|
+
function affectedKeys(node) {
|
|
106
|
+
if (node.disabled || node.disableCheckbox) return [];
|
|
107
|
+
return [...node.checkable === false ? [] : [node.key], ...node.children?.flatMap(affectedKeys) ?? []];
|
|
108
|
+
}
|
|
109
|
+
function getTreeCheckState(nodes, keys, strictly = false) {
|
|
110
|
+
const checked = new Set(keys);
|
|
111
|
+
const halfChecked = /* @__PURE__ */ new Set();
|
|
112
|
+
if (strictly) return { checked, halfChecked };
|
|
113
|
+
const explicit = new Set(keys);
|
|
114
|
+
function expand(items) {
|
|
115
|
+
for (const node of items) {
|
|
116
|
+
if (explicit.has(node.key)) affectedKeys(node).forEach((key) => checked.add(key));
|
|
117
|
+
if (node.children) expand(node.children);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
expand(nodes);
|
|
121
|
+
function fold(node) {
|
|
122
|
+
const children = node.children?.map(fold).filter((value) => value !== void 0) ?? [];
|
|
123
|
+
if (node.disabled || node.disableCheckbox) return void 0;
|
|
124
|
+
if (!children.length) return { checked: checked.has(node.key), partial: false };
|
|
125
|
+
const all = children.every((child) => child.checked);
|
|
126
|
+
const some = children.some((child) => child.checked || child.partial);
|
|
127
|
+
if (node.checkable !== false) {
|
|
128
|
+
if (all) checked.add(node.key);
|
|
129
|
+
else checked.delete(node.key);
|
|
130
|
+
if (!all && some) halfChecked.add(node.key);
|
|
131
|
+
}
|
|
132
|
+
return { checked: all, partial: !all && some };
|
|
133
|
+
}
|
|
134
|
+
nodes.forEach(fold);
|
|
135
|
+
return { checked, halfChecked };
|
|
136
|
+
}
|
|
137
|
+
function toggleTreeCheck(nodes, keys, node, strictly = false) {
|
|
138
|
+
const state = getTreeCheckState(nodes, keys, strictly);
|
|
139
|
+
const next = new Set(state.checked);
|
|
140
|
+
const checked = !next.has(node.key);
|
|
141
|
+
if (node.disabled || node.disableCheckbox || node.checkable === false) return { ...state, checkedValue: !checked };
|
|
142
|
+
(strictly ? [node.key] : affectedKeys(node)).forEach((key) => checked ? next.add(key) : next.delete(key));
|
|
143
|
+
if (!strictly && !checked) {
|
|
144
|
+
let removeParents2 = function(items) {
|
|
145
|
+
let found = false;
|
|
146
|
+
for (const item of items) {
|
|
147
|
+
const childFound = item.children ? removeParents2(item.children) : false;
|
|
148
|
+
if (childFound) next.delete(item.key);
|
|
149
|
+
if (item.key === node.key || childFound) found = true;
|
|
78
150
|
}
|
|
151
|
+
return found;
|
|
79
152
|
};
|
|
80
|
-
|
|
153
|
+
var removeParents = removeParents2;
|
|
154
|
+
removeParents2(nodes);
|
|
155
|
+
}
|
|
156
|
+
return { ...getTreeCheckState(nodes, [...next], strictly), checkedValue: checked };
|
|
81
157
|
}
|
|
82
158
|
|
|
83
|
-
// src/components/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
159
|
+
// src/components/FloatingDisplay.tsx
|
|
160
|
+
import { cloneElement, useEffect as useEffect2, useId as useId2, useLayoutEffect, useMemo as useMemo2, useRef as useRef2, useState } from "react";
|
|
161
|
+
import { createPortal } from "react-dom";
|
|
162
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
163
|
+
var FLOATING_GAP = 9;
|
|
164
|
+
var FLOATING_VIEWPORT_PADDING = 8;
|
|
165
|
+
var FLOATING_ARROW_EDGE_OFFSET = 16;
|
|
166
|
+
var activeTooltipClose;
|
|
167
|
+
function clampFloating(value, min, max) {
|
|
168
|
+
return Math.min(Math.max(value, min), Math.max(min, max));
|
|
88
169
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
170
|
+
function normalizeFloatingPlacement(placement) {
|
|
171
|
+
const aliases = {
|
|
172
|
+
topLeft: "top-start",
|
|
173
|
+
topRight: "top-end",
|
|
174
|
+
bottomLeft: "bottom-start",
|
|
175
|
+
bottomRight: "bottom-end",
|
|
176
|
+
leftTop: "left-start",
|
|
177
|
+
leftBottom: "left-end",
|
|
178
|
+
rightTop: "right-start",
|
|
179
|
+
rightBottom: "right-end"
|
|
180
|
+
};
|
|
181
|
+
return aliases[placement] ?? placement;
|
|
98
182
|
}
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
183
|
+
function resolveFloatingPosition(trigger, overlay, placement, pointAtCenter, adjust) {
|
|
184
|
+
const viewportWidth = document.documentElement.clientWidth;
|
|
185
|
+
const viewportHeight = document.documentElement.clientHeight;
|
|
186
|
+
let resolvedPlacement = normalizeFloatingPlacement(placement);
|
|
187
|
+
const side = resolvedPlacement.split("-")[0];
|
|
188
|
+
const available = { top: trigger.top, bottom: viewportHeight - trigger.bottom, left: trigger.left, right: viewportWidth - trigger.right };
|
|
189
|
+
const opposite = { top: "bottom", bottom: "top", left: "right", right: "left" };
|
|
190
|
+
const preferred = side;
|
|
191
|
+
const other = opposite[preferred];
|
|
192
|
+
const needed = (side === "top" || side === "bottom" ? overlay.height : overlay.width) + FLOATING_GAP + FLOATING_VIEWPORT_PADDING;
|
|
193
|
+
if (adjust && available[preferred] < needed && available[other] > available[preferred]) {
|
|
194
|
+
resolvedPlacement = resolvedPlacement.replace(preferred, other);
|
|
102
195
|
}
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
let
|
|
107
|
-
let left =
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
196
|
+
const vertical = resolvedPlacement.startsWith("top") || resolvedPlacement.startsWith("bottom");
|
|
197
|
+
const start = resolvedPlacement.endsWith("-start");
|
|
198
|
+
const end = resolvedPlacement.endsWith("-end");
|
|
199
|
+
let top = vertical ? resolvedPlacement.startsWith("top") ? trigger.top - overlay.height - FLOATING_GAP : trigger.bottom + FLOATING_GAP : start ? trigger.top : end ? trigger.bottom - overlay.height : trigger.top + (trigger.height - overlay.height) / 2;
|
|
200
|
+
let left = vertical ? start ? trigger.left : end ? trigger.right - overlay.width : trigger.left + (trigger.width - overlay.width) / 2 : resolvedPlacement.startsWith("left") ? trigger.left - overlay.width - FLOATING_GAP : trigger.right + FLOATING_GAP;
|
|
201
|
+
if (adjust) {
|
|
202
|
+
if (vertical) left = clampFloating(left, FLOATING_VIEWPORT_PADDING, viewportWidth - overlay.width - FLOATING_VIEWPORT_PADDING);
|
|
203
|
+
else top = clampFloating(top, FLOATING_VIEWPORT_PADDING, viewportHeight - overlay.height - FLOATING_VIEWPORT_PADDING);
|
|
204
|
+
}
|
|
205
|
+
const result = { top, left, placement: resolvedPlacement };
|
|
206
|
+
const size = vertical ? trigger.width : trigger.height;
|
|
207
|
+
const anchorStart = vertical ? trigger.left : trigger.top;
|
|
208
|
+
const edge = Math.min(size / 2, FLOATING_ARROW_EDGE_OFFSET + 4);
|
|
209
|
+
const target = anchorStart + (pointAtCenter || !start && !end ? size / 2 : start ? edge : size - edge);
|
|
210
|
+
if (vertical) result.arrowX = clampFloating(target - left - 4, 8, overlay.width - 16);
|
|
211
|
+
else result.arrowY = clampFloating(target - top - 4, 8, overlay.height - 16);
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
function isFloatingAnchorHidden(anchor, rect) {
|
|
215
|
+
let left = 0, top = 0, right = document.documentElement.clientWidth, bottom = document.documentElement.clientHeight;
|
|
216
|
+
for (let parent = anchor.parentElement; parent; parent = parent.parentElement) {
|
|
217
|
+
const css = getComputedStyle(parent);
|
|
218
|
+
const bounds = parent.getBoundingClientRect();
|
|
219
|
+
if (/(auto|scroll|hidden|clip)/.test(css.overflowX)) {
|
|
220
|
+
left = Math.max(left, bounds.left);
|
|
221
|
+
right = Math.min(right, bounds.right);
|
|
222
|
+
}
|
|
223
|
+
if (/(auto|scroll|hidden|clip)/.test(css.overflowY)) {
|
|
224
|
+
top = Math.max(top, bounds.top);
|
|
225
|
+
bottom = Math.min(bottom, bounds.bottom);
|
|
123
226
|
}
|
|
124
|
-
parent = parent.parentElement;
|
|
125
227
|
}
|
|
126
|
-
return
|
|
127
|
-
top,
|
|
128
|
-
right,
|
|
129
|
-
bottom,
|
|
130
|
-
left,
|
|
131
|
-
width: Math.max(0, right - left),
|
|
132
|
-
height: Math.max(0, bottom - top)
|
|
133
|
-
};
|
|
228
|
+
return rect.right <= left || rect.left >= right || rect.bottom <= top || rect.top >= bottom;
|
|
134
229
|
}
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
230
|
+
function Floating({
|
|
231
|
+
children,
|
|
232
|
+
content,
|
|
233
|
+
placement = "top",
|
|
234
|
+
trigger = "hover",
|
|
235
|
+
open,
|
|
236
|
+
defaultOpen = false,
|
|
237
|
+
mouseEnterDelay = 0.1,
|
|
238
|
+
mouseLeaveDelay = 0.1,
|
|
239
|
+
arrow = true,
|
|
240
|
+
autoAdjustOverflow = true,
|
|
241
|
+
color,
|
|
242
|
+
className = "",
|
|
243
|
+
overlayClassName = "",
|
|
244
|
+
role = "tooltip",
|
|
245
|
+
onOpenChange
|
|
246
|
+
}) {
|
|
247
|
+
const rootRef = useRef2(null);
|
|
248
|
+
const triggerElementRef = useRef2(null);
|
|
249
|
+
const overlayRef = useRef2(null);
|
|
250
|
+
const enterTimer = useRef2();
|
|
251
|
+
const leaveTimer = useRef2();
|
|
252
|
+
const contentId = useId2();
|
|
253
|
+
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
254
|
+
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
255
|
+
const [position, setPosition] = useState();
|
|
256
|
+
const setVisibleRef = useRef2(setVisible);
|
|
257
|
+
setVisibleRef.current = setVisible;
|
|
258
|
+
const closeSelfRef = useRef2();
|
|
259
|
+
if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
|
|
260
|
+
const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
|
|
261
|
+
function openNow() {
|
|
262
|
+
if (exclusiveTooltip && activeTooltipClose !== closeSelfRef.current) {
|
|
263
|
+
activeTooltipClose?.();
|
|
264
|
+
activeTooltipClose = closeSelfRef.current;
|
|
265
|
+
}
|
|
266
|
+
setVisible(true);
|
|
267
|
+
}
|
|
268
|
+
function closeNow() {
|
|
269
|
+
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
270
|
+
setVisible(false);
|
|
271
|
+
}
|
|
272
|
+
function clearTimers() {
|
|
273
|
+
window.clearTimeout(enterTimer.current);
|
|
274
|
+
window.clearTimeout(leaveTimer.current);
|
|
275
|
+
}
|
|
276
|
+
function show(delay = 0) {
|
|
277
|
+
clearTimers();
|
|
278
|
+
if (delay <= 0) openNow();
|
|
279
|
+
else enterTimer.current = window.setTimeout(openNow, delay * 1e3);
|
|
280
|
+
}
|
|
281
|
+
function hide(delay = 0) {
|
|
282
|
+
clearTimers();
|
|
283
|
+
if (delay <= 0) closeNow();
|
|
284
|
+
else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
|
|
285
|
+
}
|
|
147
286
|
useEffect2(() => {
|
|
148
|
-
if (
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
document.body.append(layer);
|
|
153
|
-
const entries = /* @__PURE__ */ new Map();
|
|
154
|
-
let scanFrame = 0;
|
|
155
|
-
let updateFrame = 0;
|
|
156
|
-
const setEntryVisible = (entry, visible) => {
|
|
157
|
-
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
158
|
-
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
159
|
-
};
|
|
160
|
-
const showEntry = (entry) => {
|
|
161
|
-
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
162
|
-
entry.hideTimer = null;
|
|
163
|
-
setEntryVisible(entry, true);
|
|
287
|
+
if (!visible || !triggers.includes("click")) return;
|
|
288
|
+
const close = (event) => {
|
|
289
|
+
const target = event.target;
|
|
290
|
+
if (!rootRef.current?.contains(target) && !overlayRef.current?.contains(target)) closeNow();
|
|
164
291
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
292
|
+
document.addEventListener("pointerdown", close);
|
|
293
|
+
return () => document.removeEventListener("pointerdown", close);
|
|
294
|
+
}, [triggers.join("|"), visible]);
|
|
295
|
+
useLayoutEffect(() => {
|
|
296
|
+
if (!visible) {
|
|
297
|
+
setPosition(void 0);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const getAnchor = () => {
|
|
301
|
+
const root = rootRef.current;
|
|
302
|
+
const target = triggerElementRef.current;
|
|
303
|
+
return target && root?.contains(target) ? target : root?.firstElementChild ?? root;
|
|
171
304
|
};
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (!horizontalTrack.hidden) {
|
|
181
|
-
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
182
|
-
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
183
|
-
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
184
|
-
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
185
|
-
horizontalTrack.style.left = `${rect.left}px`;
|
|
186
|
-
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
187
|
-
horizontalTrack.style.width = `${trackWidth}px`;
|
|
188
|
-
horizontalTrack.style.height = `${thickness}px`;
|
|
189
|
-
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
190
|
-
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
191
|
-
}
|
|
192
|
-
if (!verticalTrack.hidden) {
|
|
193
|
-
const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
|
|
194
|
-
const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
|
|
195
|
-
const travel = Math.max(0, trackHeight - thumbHeight);
|
|
196
|
-
const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
|
|
197
|
-
verticalTrack.style.left = `${rect.right - thickness}px`;
|
|
198
|
-
verticalTrack.style.top = `${rect.top}px`;
|
|
199
|
-
verticalTrack.style.width = `${thickness}px`;
|
|
200
|
-
verticalTrack.style.height = `${trackHeight}px`;
|
|
201
|
-
verticalThumb.style.height = `${thumbHeight}px`;
|
|
202
|
-
verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
|
|
305
|
+
const update = () => {
|
|
306
|
+
if (!rootRef.current || !overlayRef.current) return;
|
|
307
|
+
const anchor2 = getAnchor();
|
|
308
|
+
if (anchor2) {
|
|
309
|
+
const rect = anchor2.getBoundingClientRect();
|
|
310
|
+
const next = resolveFloatingPosition(rect, overlayRef.current.getBoundingClientRect(), placement, typeof arrow === "object" && !!arrow.pointAtCenter, autoAdjustOverflow);
|
|
311
|
+
next.hidden = isFloatingAnchorHidden(anchor2, rect);
|
|
312
|
+
setPosition(next);
|
|
203
313
|
}
|
|
204
314
|
};
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
};
|
|
218
|
-
const onTrackPointerLeave = () => {
|
|
219
|
-
entry.hoveringTrack = false;
|
|
220
|
-
scheduleHide(entry);
|
|
221
|
-
};
|
|
222
|
-
const onTrackPointerDown = (event) => {
|
|
223
|
-
if (event.target === thumb || event.button !== 0) return;
|
|
224
|
-
event.preventDefault();
|
|
225
|
-
event.stopPropagation();
|
|
226
|
-
const trackRect = track.getBoundingClientRect();
|
|
227
|
-
const thumbRect = thumb.getBoundingClientRect();
|
|
228
|
-
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
229
|
-
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
230
|
-
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
231
|
-
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
232
|
-
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
233
|
-
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
234
|
-
};
|
|
235
|
-
const onThumbPointerDown = (event) => {
|
|
236
|
-
if (event.button !== 0) return;
|
|
237
|
-
event.preventDefault();
|
|
238
|
-
event.stopPropagation();
|
|
239
|
-
entry.dragging = true;
|
|
240
|
-
showEntry(entry);
|
|
241
|
-
thumb.setPointerCapture(event.pointerId);
|
|
242
|
-
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
243
|
-
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
244
|
-
const trackRect = track.getBoundingClientRect();
|
|
245
|
-
const thumbRect = thumb.getBoundingClientRect();
|
|
246
|
-
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
247
|
-
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
248
|
-
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
249
|
-
const travel = Math.max(1, trackLength - thumbLength);
|
|
250
|
-
const onPointerMove = (moveEvent) => {
|
|
251
|
-
if (moveEvent.pointerId !== event.pointerId) return;
|
|
252
|
-
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
253
|
-
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
254
|
-
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
255
|
-
else target.scrollLeft = nextScroll;
|
|
256
|
-
};
|
|
257
|
-
const onPointerUp = (upEvent) => {
|
|
258
|
-
if (upEvent.pointerId !== event.pointerId) return;
|
|
259
|
-
entry.dragging = false;
|
|
260
|
-
thumb.releasePointerCapture(event.pointerId);
|
|
261
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
262
|
-
window.removeEventListener("pointerup", onPointerUp);
|
|
263
|
-
window.removeEventListener("pointercancel", onPointerUp);
|
|
264
|
-
scheduleHide(entry);
|
|
265
|
-
};
|
|
266
|
-
window.addEventListener("pointermove", onPointerMove);
|
|
267
|
-
window.addEventListener("pointerup", onPointerUp);
|
|
268
|
-
window.addEventListener("pointercancel", onPointerUp);
|
|
269
|
-
};
|
|
270
|
-
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
271
|
-
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
272
|
-
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
273
|
-
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
274
|
-
return () => {
|
|
275
|
-
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
276
|
-
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
277
|
-
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
278
|
-
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
279
|
-
};
|
|
315
|
+
update();
|
|
316
|
+
window.addEventListener("resize", update);
|
|
317
|
+
window.addEventListener("scroll", update, true);
|
|
318
|
+
const observer = new ResizeObserver(update);
|
|
319
|
+
if (rootRef.current) observer.observe(rootRef.current);
|
|
320
|
+
const anchor = getAnchor();
|
|
321
|
+
if (anchor) observer.observe(anchor);
|
|
322
|
+
if (overlayRef.current) observer.observe(overlayRef.current);
|
|
323
|
+
return () => {
|
|
324
|
+
window.removeEventListener("resize", update);
|
|
325
|
+
window.removeEventListener("scroll", update, true);
|
|
326
|
+
observer.disconnect();
|
|
280
327
|
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const entry = {
|
|
315
|
-
target,
|
|
316
|
-
horizontalTrack: horizontal.track,
|
|
317
|
-
horizontalThumb: horizontal.thumb,
|
|
318
|
-
verticalTrack: vertical.track,
|
|
319
|
-
verticalThumb: vertical.thumb,
|
|
320
|
-
hideTimer: null,
|
|
321
|
-
hoveringTarget: target.matches(":hover"),
|
|
322
|
-
hoveringTrack: false,
|
|
323
|
-
dragging: false,
|
|
324
|
-
cleanup: () => void 0
|
|
325
|
-
};
|
|
326
|
-
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
327
|
-
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
328
|
-
entry.cleanup = () => {
|
|
329
|
-
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
330
|
-
cleanupHorizontal();
|
|
331
|
-
cleanupVertical();
|
|
332
|
-
target.removeEventListener("pointerenter", onPointerEnter);
|
|
333
|
-
target.removeEventListener("pointerleave", onPointerLeave);
|
|
334
|
-
target.removeEventListener("scroll", onScroll);
|
|
335
|
-
resizeObserver.unobserve(target);
|
|
336
|
-
target.removeAttribute("data-sia-floating-scrollbar");
|
|
337
|
-
horizontal.track.remove();
|
|
338
|
-
vertical.track.remove();
|
|
339
|
-
};
|
|
340
|
-
entries.set(target, entry);
|
|
341
|
-
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
342
|
-
resizeObserver.observe(target);
|
|
343
|
-
updateEntry(entry);
|
|
344
|
-
if (entry.hoveringTarget) showEntry(entry);
|
|
345
|
-
};
|
|
346
|
-
const removeTarget = (target) => {
|
|
347
|
-
const entry = entries.get(target);
|
|
348
|
-
if (!entry) return;
|
|
349
|
-
entry.cleanup();
|
|
350
|
-
entries.delete(target);
|
|
351
|
-
};
|
|
352
|
-
const scanTargets = () => {
|
|
353
|
-
scanFrame = 0;
|
|
354
|
-
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
355
|
-
const nextTargets = /* @__PURE__ */ new Set();
|
|
356
|
-
candidates.forEach((target) => {
|
|
357
|
-
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
358
|
-
nextTargets.add(target);
|
|
359
|
-
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
entries.forEach((_entry, target) => {
|
|
363
|
-
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
364
|
-
else updateEntry(_entry);
|
|
365
|
-
});
|
|
366
|
-
};
|
|
367
|
-
const scheduleScan = () => {
|
|
368
|
-
if (scanFrame) return;
|
|
369
|
-
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
370
|
-
};
|
|
371
|
-
const mutationObserver = new MutationObserver((mutations) => {
|
|
372
|
-
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
373
|
-
});
|
|
374
|
-
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
375
|
-
window.addEventListener("resize", scheduleScan);
|
|
376
|
-
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
377
|
-
scheduleScan();
|
|
378
|
-
return () => {
|
|
379
|
-
mutationObserver.disconnect();
|
|
380
|
-
resizeObserver.disconnect();
|
|
381
|
-
window.removeEventListener("resize", scheduleScan);
|
|
382
|
-
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
383
|
-
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
384
|
-
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
385
|
-
entries.forEach((entry) => entry.cleanup());
|
|
386
|
-
entries.clear();
|
|
387
|
-
layer.remove();
|
|
388
|
-
};
|
|
389
|
-
}, [disabled, targetRef]);
|
|
390
|
-
return null;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// src/components/Checkbox.tsx
|
|
394
|
-
import { createContext, forwardRef, useContext, useEffect as useEffect3, useId, useMemo, useRef } from "react";
|
|
395
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
396
|
-
var CheckboxGroupContext = createContext(null);
|
|
397
|
-
var CheckboxRoot = forwardRef(function Checkbox({ value, size: sizeProp, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
|
|
398
|
-
const size = useControlSize(sizeProp);
|
|
399
|
-
const group = useContext(CheckboxGroupContext);
|
|
400
|
-
const localRef = useRef(null);
|
|
401
|
-
const fallbackId = useId();
|
|
402
|
-
const grouped = group !== null && value !== void 0;
|
|
403
|
-
const currentChecked = grouped ? group.values.includes(value) : checked;
|
|
404
|
-
useEffect3(() => {
|
|
405
|
-
if (localRef.current) localRef.current.indeterminate = indeterminate;
|
|
406
|
-
}, [indeterminate]);
|
|
407
|
-
function setRef(node) {
|
|
408
|
-
localRef.current = node;
|
|
409
|
-
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
410
|
-
else if (forwardedRef) forwardedRef.current = node;
|
|
411
|
-
}
|
|
412
|
-
return /* @__PURE__ */ jsxs("label", { className: `sia-checkbox sia-checkbox--${size}${disabled || group?.disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
|
|
413
|
-
/* @__PURE__ */ jsx(
|
|
414
|
-
"input",
|
|
328
|
+
}, [children, content, placement, visible, autoAdjustOverflow, typeof arrow === "object" && arrow.pointAtCenter]);
|
|
329
|
+
useEffect2(() => () => {
|
|
330
|
+
clearTimers();
|
|
331
|
+
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
332
|
+
}, []);
|
|
333
|
+
const child = cloneElement(children, {
|
|
334
|
+
...triggers.includes("hover") ? { onMouseEnter: (event) => {
|
|
335
|
+
triggerElementRef.current = event.currentTarget;
|
|
336
|
+
children.props.onMouseEnter?.(event);
|
|
337
|
+
show(mouseEnterDelay);
|
|
338
|
+
}, onMouseLeave: (event) => {
|
|
339
|
+
children.props.onMouseLeave?.(event);
|
|
340
|
+
hide(mouseLeaveDelay);
|
|
341
|
+
} } : {},
|
|
342
|
+
...triggers.includes("focus") ? { onFocus: (event) => {
|
|
343
|
+
triggerElementRef.current = event.currentTarget;
|
|
344
|
+
children.props.onFocus?.(event);
|
|
345
|
+
show();
|
|
346
|
+
}, onBlur: (event) => {
|
|
347
|
+
children.props.onBlur?.(event);
|
|
348
|
+
hide();
|
|
349
|
+
} } : {},
|
|
350
|
+
...triggers.includes("click") ? { onClick: (event) => {
|
|
351
|
+
triggerElementRef.current = event.currentTarget;
|
|
352
|
+
children.props.onClick?.(event);
|
|
353
|
+
if (visible) closeNow();
|
|
354
|
+
else openNow();
|
|
355
|
+
} } : {},
|
|
356
|
+
"aria-describedby": visible ? contentId : void 0
|
|
357
|
+
});
|
|
358
|
+
const overlay = visible && content !== null && content !== void 0 && typeof document !== "undefined" ? createPortal(
|
|
359
|
+
/* @__PURE__ */ jsxs2(
|
|
360
|
+
"span",
|
|
415
361
|
{
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
362
|
+
ref: overlayRef,
|
|
363
|
+
id: contentId,
|
|
364
|
+
role,
|
|
365
|
+
"data-custom-color": color ? "" : void 0,
|
|
366
|
+
className: `sia-floating__overlay sia-floating__overlay--${position?.placement ?? normalizeFloatingPlacement(placement)} ${overlayClassName}`.trim(),
|
|
367
|
+
style: {
|
|
368
|
+
"--sia-floating-color": color,
|
|
369
|
+
"--sia-floating-arrow-x": position?.arrowX == null ? void 0 : `${position.arrowX}px`,
|
|
370
|
+
"--sia-floating-arrow-y": position?.arrowY == null ? void 0 : `${position.arrowY}px`,
|
|
371
|
+
top: position?.top ?? 0,
|
|
372
|
+
left: position?.left ?? 0,
|
|
373
|
+
visibility: position && !position.hidden ? "visible" : "hidden"
|
|
374
|
+
},
|
|
375
|
+
onMouseEnter: triggers.includes("hover") ? () => show() : void 0,
|
|
376
|
+
onMouseLeave: triggers.includes("hover") ? () => hide(mouseLeaveDelay) : void 0,
|
|
377
|
+
children: [
|
|
378
|
+
content,
|
|
379
|
+
arrow ? /* @__PURE__ */ jsx2("span", { className: "sia-floating__arrow" }) : null
|
|
380
|
+
]
|
|
430
381
|
}
|
|
431
382
|
),
|
|
432
|
-
|
|
433
|
-
|
|
383
|
+
document.body
|
|
384
|
+
) : null;
|
|
385
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
386
|
+
/* @__PURE__ */ jsx2("span", { ref: rootRef, className: `sia-floating ${className}`.trim(), children: child }),
|
|
387
|
+
overlay
|
|
434
388
|
] });
|
|
435
|
-
});
|
|
436
|
-
function CheckboxGroup({
|
|
437
|
-
size: sizeProp,
|
|
438
|
-
columns,
|
|
439
|
-
direction = "horizontal",
|
|
440
|
-
gap,
|
|
441
|
-
value,
|
|
442
|
-
defaultValue = [],
|
|
443
|
-
options,
|
|
444
|
-
disabled,
|
|
445
|
-
name,
|
|
446
|
-
className = "",
|
|
447
|
-
children,
|
|
448
|
-
onChange
|
|
449
|
-
}) {
|
|
450
|
-
const size = useControlSize(sizeProp);
|
|
451
|
-
const gridColumns = columns !== void 0 && Number.isInteger(columns) && columns > 0 ? columns : void 0;
|
|
452
|
-
const layoutStyle = {
|
|
453
|
-
gridTemplateColumns: gridColumns ? `repeat(${gridColumns}, minmax(0, 1fr))` : void 0,
|
|
454
|
-
gap: gap === void 0 ? void 0 : typeof gap === "number" ? Math.max(0, gap) : `${Math.max(0, gap[0])}px ${Math.max(0, gap[1])}px`
|
|
455
|
-
};
|
|
456
|
-
const [values, setValues] = useControllableState({ value, defaultValue, onChange });
|
|
457
|
-
const context = useMemo(() => ({
|
|
458
|
-
values,
|
|
459
|
-
disabled,
|
|
460
|
-
name,
|
|
461
|
-
toggle(optionValue, checked) {
|
|
462
|
-
const next = checked ? values.includes(optionValue) ? values : [...values, optionValue] : values.filter((item) => item !== optionValue);
|
|
463
|
-
setValues(next);
|
|
464
|
-
}
|
|
465
|
-
}), [disabled, name, setValues, values]);
|
|
466
|
-
return /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx(CheckboxGroupContext.Provider, { value: context, children: /* @__PURE__ */ jsxs("div", { className: `sia-checkbox-group${gridColumns ? " sia-checkbox-group--grid" : direction === "vertical" ? " sia-checkbox-group--vertical" : ""} ${className}`.trim(), style: layoutStyle, role: "group", children: [
|
|
467
|
-
options?.map((option) => {
|
|
468
|
-
const normalized = typeof option === "object" ? option : { label: String(option), value: option };
|
|
469
|
-
return /* @__PURE__ */ jsx(CheckboxRoot, { value: normalized.value, disabled: normalized.disabled, children: normalized.label }, normalized.value);
|
|
470
|
-
}),
|
|
471
|
-
children
|
|
472
|
-
] }) }) });
|
|
473
389
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
Group: CheckboxGroup
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
// src/components/treeCheckState.ts
|
|
480
|
-
function affectedKeys(node) {
|
|
481
|
-
if (node.disabled || node.disableCheckbox) return [];
|
|
482
|
-
return [...node.checkable === false ? [] : [node.key], ...node.children?.flatMap(affectedKeys) ?? []];
|
|
390
|
+
function Tooltip(props) {
|
|
391
|
+
return /* @__PURE__ */ jsx2(Floating, { ...props, content: props.title });
|
|
483
392
|
}
|
|
484
|
-
function
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
function expand(items) {
|
|
490
|
-
for (const node of items) {
|
|
491
|
-
if (explicit.has(node.key)) affectedKeys(node).forEach((key) => checked.add(key));
|
|
492
|
-
if (node.children) expand(node.children);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
expand(nodes);
|
|
496
|
-
function fold(node) {
|
|
497
|
-
const children = node.children?.map(fold).filter((value) => value !== void 0) ?? [];
|
|
498
|
-
if (node.disabled || node.disableCheckbox) return void 0;
|
|
499
|
-
if (!children.length) return { checked: checked.has(node.key), partial: false };
|
|
500
|
-
const all = children.every((child) => child.checked);
|
|
501
|
-
const some = children.some((child) => child.checked || child.partial);
|
|
502
|
-
if (node.checkable !== false) {
|
|
503
|
-
if (all) checked.add(node.key);
|
|
504
|
-
else checked.delete(node.key);
|
|
505
|
-
if (!all && some) halfChecked.add(node.key);
|
|
506
|
-
}
|
|
507
|
-
return { checked: all, partial: !all && some };
|
|
508
|
-
}
|
|
509
|
-
nodes.forEach(fold);
|
|
510
|
-
return { checked, halfChecked };
|
|
511
|
-
}
|
|
512
|
-
function toggleTreeCheck(nodes, keys, node, strictly = false) {
|
|
513
|
-
const state = getTreeCheckState(nodes, keys, strictly);
|
|
514
|
-
const next = new Set(state.checked);
|
|
515
|
-
const checked = !next.has(node.key);
|
|
516
|
-
if (node.disabled || node.disableCheckbox || node.checkable === false) return { ...state, checkedValue: !checked };
|
|
517
|
-
(strictly ? [node.key] : affectedKeys(node)).forEach((key) => checked ? next.add(key) : next.delete(key));
|
|
518
|
-
if (!strictly && !checked) {
|
|
519
|
-
let removeParents2 = function(items) {
|
|
520
|
-
let found = false;
|
|
521
|
-
for (const item of items) {
|
|
522
|
-
const childFound = item.children ? removeParents2(item.children) : false;
|
|
523
|
-
if (childFound) next.delete(item.key);
|
|
524
|
-
if (item.key === node.key || childFound) found = true;
|
|
525
|
-
}
|
|
526
|
-
return found;
|
|
527
|
-
};
|
|
528
|
-
var removeParents = removeParents2;
|
|
529
|
-
removeParents2(nodes);
|
|
530
|
-
}
|
|
531
|
-
return { ...getTreeCheckState(nodes, [...next], strictly), checkedValue: checked };
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// src/components/FloatingDisplay.tsx
|
|
535
|
-
import { cloneElement, useEffect as useEffect4, useId as useId2, useLayoutEffect, useMemo as useMemo2, useRef as useRef2, useState } from "react";
|
|
536
|
-
import { createPortal } from "react-dom";
|
|
537
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
538
|
-
var FLOATING_GAP = 9;
|
|
539
|
-
var FLOATING_VIEWPORT_PADDING = 8;
|
|
540
|
-
var FLOATING_ARROW_EDGE_OFFSET = 16;
|
|
541
|
-
var activeTooltipClose;
|
|
542
|
-
function clampFloating(value, min, max) {
|
|
543
|
-
return Math.min(Math.max(value, min), Math.max(min, max));
|
|
544
|
-
}
|
|
545
|
-
function resolveFloatingPosition(trigger, overlay, placement) {
|
|
546
|
-
const viewportWidth = document.documentElement.clientWidth;
|
|
547
|
-
const viewportHeight = document.documentElement.clientHeight;
|
|
548
|
-
let resolvedPlacement = placement;
|
|
549
|
-
if (placement.startsWith("top") && trigger.top - overlay.height - FLOATING_GAP < FLOATING_VIEWPORT_PADDING && trigger.bottom + overlay.height + FLOATING_GAP <= viewportHeight - FLOATING_VIEWPORT_PADDING) {
|
|
550
|
-
resolvedPlacement = placement.replace("top", "bottom");
|
|
551
|
-
} else if (placement.startsWith("bottom") && trigger.bottom + overlay.height + FLOATING_GAP > viewportHeight - FLOATING_VIEWPORT_PADDING && trigger.top - overlay.height - FLOATING_GAP >= FLOATING_VIEWPORT_PADDING) {
|
|
552
|
-
resolvedPlacement = placement.replace("bottom", "top");
|
|
553
|
-
} else if (placement === "left" && trigger.left - overlay.width - FLOATING_GAP < FLOATING_VIEWPORT_PADDING && trigger.right + overlay.width + FLOATING_GAP <= viewportWidth - FLOATING_VIEWPORT_PADDING) {
|
|
554
|
-
resolvedPlacement = "right";
|
|
555
|
-
} else if (placement === "right" && trigger.right + overlay.width + FLOATING_GAP > viewportWidth - FLOATING_VIEWPORT_PADDING && trigger.left - overlay.width - FLOATING_GAP >= FLOATING_VIEWPORT_PADDING) {
|
|
556
|
-
resolvedPlacement = "left";
|
|
557
|
-
}
|
|
558
|
-
let top = trigger.top;
|
|
559
|
-
let left = trigger.left;
|
|
560
|
-
if (resolvedPlacement.startsWith("top") || resolvedPlacement.startsWith("bottom")) {
|
|
561
|
-
top = resolvedPlacement.startsWith("top") ? trigger.top - overlay.height - FLOATING_GAP : trigger.bottom + FLOATING_GAP;
|
|
562
|
-
left = resolvedPlacement.endsWith("-start") ? trigger.left : resolvedPlacement.endsWith("-end") ? trigger.right - overlay.width : trigger.left + (trigger.width - overlay.width) / 2;
|
|
563
|
-
} else {
|
|
564
|
-
top = trigger.top + (trigger.height - overlay.height) / 2;
|
|
565
|
-
left = resolvedPlacement === "left" ? trigger.left - overlay.width - FLOATING_GAP : trigger.right + FLOATING_GAP;
|
|
566
|
-
}
|
|
567
|
-
top = clampFloating(top, FLOATING_VIEWPORT_PADDING, viewportHeight - overlay.height - FLOATING_VIEWPORT_PADDING);
|
|
568
|
-
left = clampFloating(left, FLOATING_VIEWPORT_PADDING, viewportWidth - overlay.width - FLOATING_VIEWPORT_PADDING);
|
|
569
|
-
const result = { top, left, placement: resolvedPlacement };
|
|
570
|
-
if (resolvedPlacement.startsWith("top") || resolvedPlacement.startsWith("bottom")) {
|
|
571
|
-
result.arrowX = resolvedPlacement.endsWith("-start") ? clampFloating(FLOATING_ARROW_EDGE_OFFSET, 8, overlay.width - 16) : resolvedPlacement.endsWith("-end") ? clampFloating(overlay.width - FLOATING_ARROW_EDGE_OFFSET - 8, 8, overlay.width - 16) : clampFloating(trigger.left + trigger.width / 2 - left - 4, 8, overlay.width - 16);
|
|
572
|
-
} else {
|
|
573
|
-
result.arrowY = clampFloating(trigger.top + trigger.height / 2 - top - 4, 8, overlay.height - 16);
|
|
574
|
-
}
|
|
575
|
-
return result;
|
|
576
|
-
}
|
|
577
|
-
function Floating({
|
|
578
|
-
children,
|
|
579
|
-
content,
|
|
580
|
-
placement = "top",
|
|
581
|
-
trigger = "hover",
|
|
582
|
-
open,
|
|
583
|
-
defaultOpen = false,
|
|
584
|
-
mouseEnterDelay = 0.1,
|
|
585
|
-
mouseLeaveDelay = 0.1,
|
|
586
|
-
arrow = true,
|
|
587
|
-
color,
|
|
588
|
-
className = "",
|
|
589
|
-
overlayClassName = "",
|
|
590
|
-
role = "tooltip",
|
|
591
|
-
onOpenChange
|
|
592
|
-
}) {
|
|
593
|
-
const rootRef = useRef2(null);
|
|
594
|
-
const overlayRef = useRef2(null);
|
|
595
|
-
const enterTimer = useRef2();
|
|
596
|
-
const leaveTimer = useRef2();
|
|
597
|
-
const contentId = useId2();
|
|
598
|
-
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
599
|
-
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
600
|
-
const [position, setPosition] = useState();
|
|
601
|
-
const setVisibleRef = useRef2(setVisible);
|
|
602
|
-
setVisibleRef.current = setVisible;
|
|
603
|
-
const closeSelfRef = useRef2();
|
|
604
|
-
if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
|
|
605
|
-
const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
|
|
606
|
-
function openNow() {
|
|
607
|
-
if (exclusiveTooltip && activeTooltipClose !== closeSelfRef.current) {
|
|
608
|
-
activeTooltipClose?.();
|
|
609
|
-
activeTooltipClose = closeSelfRef.current;
|
|
610
|
-
}
|
|
611
|
-
setVisible(true);
|
|
612
|
-
}
|
|
613
|
-
function closeNow() {
|
|
614
|
-
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
615
|
-
setVisible(false);
|
|
616
|
-
}
|
|
617
|
-
function clearTimers() {
|
|
618
|
-
window.clearTimeout(enterTimer.current);
|
|
619
|
-
window.clearTimeout(leaveTimer.current);
|
|
620
|
-
}
|
|
621
|
-
function show(delay = 0) {
|
|
622
|
-
clearTimers();
|
|
623
|
-
if (delay <= 0) openNow();
|
|
624
|
-
else enterTimer.current = window.setTimeout(openNow, delay * 1e3);
|
|
625
|
-
}
|
|
626
|
-
function hide(delay = 0) {
|
|
627
|
-
clearTimers();
|
|
628
|
-
if (delay <= 0) closeNow();
|
|
629
|
-
else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
|
|
630
|
-
}
|
|
631
|
-
useEffect4(() => {
|
|
632
|
-
if (!visible || !triggers.includes("click")) return;
|
|
633
|
-
const close = (event) => {
|
|
634
|
-
const target = event.target;
|
|
635
|
-
if (!rootRef.current?.contains(target) && !overlayRef.current?.contains(target)) closeNow();
|
|
636
|
-
};
|
|
637
|
-
document.addEventListener("pointerdown", close);
|
|
638
|
-
return () => document.removeEventListener("pointerdown", close);
|
|
639
|
-
}, [triggers.join("|"), visible]);
|
|
640
|
-
useLayoutEffect(() => {
|
|
641
|
-
if (!visible) {
|
|
642
|
-
setPosition(void 0);
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
const update = () => {
|
|
646
|
-
if (!rootRef.current || !overlayRef.current) return;
|
|
647
|
-
setPosition(resolveFloatingPosition(rootRef.current.getBoundingClientRect(), overlayRef.current.getBoundingClientRect(), placement));
|
|
648
|
-
};
|
|
649
|
-
update();
|
|
650
|
-
window.addEventListener("resize", update);
|
|
651
|
-
window.addEventListener("scroll", update, true);
|
|
652
|
-
const observer = new ResizeObserver(update);
|
|
653
|
-
if (rootRef.current) observer.observe(rootRef.current);
|
|
654
|
-
if (overlayRef.current) observer.observe(overlayRef.current);
|
|
655
|
-
return () => {
|
|
656
|
-
window.removeEventListener("resize", update);
|
|
657
|
-
window.removeEventListener("scroll", update, true);
|
|
658
|
-
observer.disconnect();
|
|
659
|
-
};
|
|
660
|
-
}, [children, content, placement, visible]);
|
|
661
|
-
useEffect4(() => () => {
|
|
662
|
-
clearTimers();
|
|
663
|
-
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
664
|
-
}, []);
|
|
665
|
-
const child = cloneElement(children, {
|
|
666
|
-
...triggers.includes("hover") ? { onMouseEnter: (event) => {
|
|
667
|
-
children.props.onMouseEnter?.(event);
|
|
668
|
-
show(mouseEnterDelay);
|
|
669
|
-
}, onMouseLeave: (event) => {
|
|
670
|
-
children.props.onMouseLeave?.(event);
|
|
671
|
-
hide(mouseLeaveDelay);
|
|
672
|
-
} } : {},
|
|
673
|
-
...triggers.includes("focus") ? { onFocus: (event) => {
|
|
674
|
-
children.props.onFocus?.(event);
|
|
675
|
-
show();
|
|
676
|
-
}, onBlur: (event) => {
|
|
677
|
-
children.props.onBlur?.(event);
|
|
678
|
-
hide();
|
|
679
|
-
} } : {},
|
|
680
|
-
...triggers.includes("click") ? { onClick: (event) => {
|
|
681
|
-
children.props.onClick?.(event);
|
|
682
|
-
if (visible) closeNow();
|
|
683
|
-
else openNow();
|
|
684
|
-
} } : {},
|
|
685
|
-
"aria-describedby": visible ? contentId : void 0
|
|
686
|
-
});
|
|
687
|
-
const overlay = visible && content !== null && content !== void 0 && typeof document !== "undefined" ? createPortal(
|
|
688
|
-
/* @__PURE__ */ jsxs2(
|
|
689
|
-
"span",
|
|
690
|
-
{
|
|
691
|
-
ref: overlayRef,
|
|
692
|
-
id: contentId,
|
|
693
|
-
role,
|
|
694
|
-
"data-custom-color": color ? "" : void 0,
|
|
695
|
-
className: `sia-floating__overlay sia-floating__overlay--${position?.placement ?? placement} ${overlayClassName}`.trim(),
|
|
696
|
-
style: {
|
|
697
|
-
"--sia-floating-color": color,
|
|
698
|
-
"--sia-floating-arrow-x": position?.arrowX == null ? void 0 : `${position.arrowX}px`,
|
|
699
|
-
"--sia-floating-arrow-y": position?.arrowY == null ? void 0 : `${position.arrowY}px`,
|
|
700
|
-
top: position?.top ?? 0,
|
|
701
|
-
left: position?.left ?? 0,
|
|
702
|
-
visibility: position ? "visible" : "hidden"
|
|
703
|
-
},
|
|
704
|
-
onMouseEnter: triggers.includes("hover") ? () => show() : void 0,
|
|
705
|
-
onMouseLeave: triggers.includes("hover") ? () => hide(mouseLeaveDelay) : void 0,
|
|
706
|
-
children: [
|
|
707
|
-
content,
|
|
708
|
-
arrow ? /* @__PURE__ */ jsx2("span", { className: "sia-floating__arrow" }) : null
|
|
709
|
-
]
|
|
710
|
-
}
|
|
711
|
-
),
|
|
712
|
-
document.body
|
|
713
|
-
) : null;
|
|
714
|
-
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
715
|
-
/* @__PURE__ */ jsx2("span", { ref: rootRef, className: `sia-floating ${className}`.trim(), children: child }),
|
|
716
|
-
overlay
|
|
717
|
-
] });
|
|
718
|
-
}
|
|
719
|
-
function Tooltip(props) {
|
|
720
|
-
return /* @__PURE__ */ jsx2(Floating, { ...props, content: props.title });
|
|
721
|
-
}
|
|
722
|
-
function Popover({ title, content, trigger = "click", overlayClassName = "", ...props }) {
|
|
723
|
-
return /* @__PURE__ */ jsx2(Floating, { ...props, trigger, role: "dialog", overlayClassName: `sia-popover ${overlayClassName}`.trim(), content: /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
724
|
-
title ? /* @__PURE__ */ jsx2("strong", { className: "sia-popover__title", children: title }) : null,
|
|
725
|
-
/* @__PURE__ */ jsx2("span", { className: "sia-popover__content", children: content })
|
|
726
|
-
] }) });
|
|
393
|
+
function Popover({ title, content, trigger = "click", overlayClassName = "", ...props }) {
|
|
394
|
+
return /* @__PURE__ */ jsx2(Floating, { ...props, trigger, role: "dialog", overlayClassName: `sia-popover ${overlayClassName}`.trim(), content: /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
395
|
+
title ? /* @__PURE__ */ jsx2("strong", { className: "sia-popover__title", children: title }) : null,
|
|
396
|
+
/* @__PURE__ */ jsx2("span", { className: "sia-popover__content", children: content })
|
|
397
|
+
] }) });
|
|
727
398
|
}
|
|
728
399
|
function Timeline({ items = [], mode = "left", pending = false, pendingDot, reverse = false, className = "", ...props }) {
|
|
729
400
|
const values = [...items, ...pending ? [{ children: pending === true ? "\u52A0\u8F7D\u4E2D..." : pending, dot: pendingDot ?? /* @__PURE__ */ jsx2(Icon, { name: "loader", className: "sia-spin-icon" }) }] : []];
|
|
@@ -978,11 +649,11 @@ function Tree({
|
|
|
978
649
|
}
|
|
979
650
|
|
|
980
651
|
// src/components/Modal.tsx
|
|
981
|
-
import { forwardRef as forwardRef2, useEffect as
|
|
652
|
+
import { forwardRef as forwardRef2, useEffect as useEffect4, useId as useId3, useRef as useRef4, useState as useState2 } from "react";
|
|
982
653
|
import { createRoot } from "react-dom/client";
|
|
983
654
|
|
|
984
655
|
// src/components/Overlay.tsx
|
|
985
|
-
import { useEffect as
|
|
656
|
+
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
986
657
|
import { createPortal as createPortal2 } from "react-dom";
|
|
987
658
|
var bodyLockCount = 0;
|
|
988
659
|
var previousBodyOverflow = "";
|
|
@@ -1007,7 +678,7 @@ function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
|
|
|
1007
678
|
const overlayIdRef = useRef3(/* @__PURE__ */ Symbol("sia-overlay"));
|
|
1008
679
|
const closeRef = useRef3(onRequestClose);
|
|
1009
680
|
closeRef.current = onRequestClose;
|
|
1010
|
-
|
|
681
|
+
useEffect3(() => {
|
|
1011
682
|
if (!open || typeof document === "undefined") return void 0;
|
|
1012
683
|
const overlayId = overlayIdRef.current;
|
|
1013
684
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -1045,247 +716,622 @@ function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
|
|
|
1045
716
|
}
|
|
1046
717
|
document.addEventListener("keydown", handleKeyDown);
|
|
1047
718
|
return () => {
|
|
1048
|
-
window.clearTimeout(focusTimer);
|
|
1049
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
1050
|
-
const index = overlayStack.lastIndexOf(overlayId);
|
|
1051
|
-
if (index >= 0) overlayStack.splice(index, 1);
|
|
1052
|
-
unlockBody();
|
|
1053
|
-
previouslyFocused?.focus({ preventScroll: true });
|
|
719
|
+
window.clearTimeout(focusTimer);
|
|
720
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
721
|
+
const index = overlayStack.lastIndexOf(overlayId);
|
|
722
|
+
if (index >= 0) overlayStack.splice(index, 1);
|
|
723
|
+
unlockBody();
|
|
724
|
+
previouslyFocused?.focus({ preventScroll: true });
|
|
725
|
+
};
|
|
726
|
+
}, [keyboard, open, panelRef]);
|
|
727
|
+
}
|
|
728
|
+
function OverlayPortal({ children, container }) {
|
|
729
|
+
if (typeof document === "undefined") return null;
|
|
730
|
+
const target = typeof container === "function" ? container() : container ?? document.body;
|
|
731
|
+
return createPortal2(children, target);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// src/components/Modal.tsx
|
|
735
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
736
|
+
var modalHandles = /* @__PURE__ */ new Set();
|
|
737
|
+
var MODAL_MOTION_DURATION = 220;
|
|
738
|
+
var typeIcons = {
|
|
739
|
+
info: /* @__PURE__ */ jsx3(Icon, { name: "info", size: 23 }),
|
|
740
|
+
success: /* @__PURE__ */ jsx3(Icon, { name: "circle-check", size: 23 }),
|
|
741
|
+
warning: /* @__PURE__ */ jsx3(Icon, { name: "warning", size: 23 }),
|
|
742
|
+
error: /* @__PURE__ */ jsx3(Icon, { name: "circle-close", size: 23 }),
|
|
743
|
+
confirm: /* @__PURE__ */ jsx3(Icon, { name: "question", size: 23 })
|
|
744
|
+
};
|
|
745
|
+
var ModalRoot = forwardRef2(function Modal({
|
|
746
|
+
open,
|
|
747
|
+
title,
|
|
748
|
+
children,
|
|
749
|
+
footer,
|
|
750
|
+
footerExtra,
|
|
751
|
+
type = "default",
|
|
752
|
+
okText = "\u786E\u5B9A",
|
|
753
|
+
cancelText = "\u53D6\u6D88",
|
|
754
|
+
showCancel = type === "default" || type === "confirm",
|
|
755
|
+
confirmLoading = false,
|
|
756
|
+
okButtonProps,
|
|
757
|
+
cancelButtonProps,
|
|
758
|
+
closable = true,
|
|
759
|
+
maskClosable = true,
|
|
760
|
+
keyboard = true,
|
|
761
|
+
centered = false,
|
|
762
|
+
width = 520,
|
|
763
|
+
height,
|
|
764
|
+
zIndex = 1e3,
|
|
765
|
+
getContainer,
|
|
766
|
+
onOk,
|
|
767
|
+
onCancel,
|
|
768
|
+
onOpenChange,
|
|
769
|
+
afterOpenChange,
|
|
770
|
+
className = "",
|
|
771
|
+
style,
|
|
772
|
+
...props
|
|
773
|
+
}, forwardedRef) {
|
|
774
|
+
const localRef = useRef4(null);
|
|
775
|
+
const titleId = useId3();
|
|
776
|
+
const [submitting, setSubmitting] = useState2(false);
|
|
777
|
+
const [rendered, setRendered] = useState2(open);
|
|
778
|
+
const [closing, setClosing] = useState2(false);
|
|
779
|
+
const afterOpenChangeRef = useRef4(afterOpenChange);
|
|
780
|
+
afterOpenChangeRef.current = afterOpenChange;
|
|
781
|
+
const submitLock = useRef4(false);
|
|
782
|
+
useEffect4(() => {
|
|
783
|
+
if (!open || !rendered) return void 0;
|
|
784
|
+
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
785
|
+
return () => window.clearTimeout(timer);
|
|
786
|
+
}, [open, rendered]);
|
|
787
|
+
useEffect4(() => {
|
|
788
|
+
if (open) {
|
|
789
|
+
setRendered(true);
|
|
790
|
+
setClosing(false);
|
|
791
|
+
return void 0;
|
|
792
|
+
}
|
|
793
|
+
if (!rendered) return void 0;
|
|
794
|
+
setClosing(true);
|
|
795
|
+
const timer = window.setTimeout(() => {
|
|
796
|
+
setRendered(false);
|
|
797
|
+
setClosing(false);
|
|
798
|
+
afterOpenChangeRef.current?.(false);
|
|
799
|
+
}, MODAL_MOTION_DURATION);
|
|
800
|
+
return () => window.clearTimeout(timer);
|
|
801
|
+
}, [open, rendered]);
|
|
802
|
+
function setRef(node) {
|
|
803
|
+
localRef.current = node;
|
|
804
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
805
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
806
|
+
}
|
|
807
|
+
function requestClose() {
|
|
808
|
+
if (submitting || confirmLoading) return;
|
|
809
|
+
onCancel?.();
|
|
810
|
+
onOpenChange?.(false);
|
|
811
|
+
}
|
|
812
|
+
async function handleOk() {
|
|
813
|
+
if (submitLock.current || confirmLoading) return;
|
|
814
|
+
submitLock.current = true;
|
|
815
|
+
if (!onOk) {
|
|
816
|
+
onOpenChange?.(false);
|
|
817
|
+
submitLock.current = false;
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
try {
|
|
821
|
+
const result = onOk();
|
|
822
|
+
if (result instanceof Promise) {
|
|
823
|
+
setSubmitting(true);
|
|
824
|
+
const resolved = await result;
|
|
825
|
+
if (resolved !== false) onOpenChange?.(false);
|
|
826
|
+
} else if (result !== false) {
|
|
827
|
+
onOpenChange?.(false);
|
|
828
|
+
}
|
|
829
|
+
} catch {
|
|
830
|
+
return;
|
|
831
|
+
} finally {
|
|
832
|
+
submitLock.current = false;
|
|
833
|
+
setSubmitting(false);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
|
|
837
|
+
if (!rendered) return null;
|
|
838
|
+
const mergedStyle = {
|
|
839
|
+
...height !== void 0 ? { display: "flex", flexDirection: "column", height, maxHeight: "calc(100dvh - 48px)" } : {},
|
|
840
|
+
...style,
|
|
841
|
+
"--sia-modal-width": typeof width === "number" ? `${width}px` : width
|
|
842
|
+
};
|
|
843
|
+
const loading = submitting || confirmLoading;
|
|
844
|
+
const defaultFooter = /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
845
|
+
showCancel ? /* @__PURE__ */ jsx3(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
|
|
846
|
+
/* @__PURE__ */ jsx3(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
|
|
847
|
+
] });
|
|
848
|
+
return /* @__PURE__ */ jsx3(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ jsx3(
|
|
849
|
+
"div",
|
|
850
|
+
{
|
|
851
|
+
className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
|
|
852
|
+
"data-state": closing ? "closing" : "open",
|
|
853
|
+
style: { zIndex },
|
|
854
|
+
onMouseDown: (event) => {
|
|
855
|
+
if (event.target === event.currentTarget && maskClosable) requestClose();
|
|
856
|
+
},
|
|
857
|
+
children: /* @__PURE__ */ jsxs3(
|
|
858
|
+
"div",
|
|
859
|
+
{
|
|
860
|
+
ref: setRef,
|
|
861
|
+
className: `sia-modal sia-modal--${type} ${className}`.trim(),
|
|
862
|
+
style: mergedStyle,
|
|
863
|
+
role: "dialog",
|
|
864
|
+
"aria-modal": "true",
|
|
865
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
866
|
+
tabIndex: -1,
|
|
867
|
+
...withTitleTooltip(props),
|
|
868
|
+
children: [
|
|
869
|
+
/* @__PURE__ */ jsxs3("div", { className: "sia-modal__header", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
870
|
+
/* @__PURE__ */ jsxs3("div", { className: "sia-modal__heading", children: [
|
|
871
|
+
typeIcons[type] ? /* @__PURE__ */ jsx3("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
|
|
872
|
+
title ? /* @__PURE__ */ jsx3("strong", { id: titleId, children: title }) : null
|
|
873
|
+
] }),
|
|
874
|
+
closable ? /* @__PURE__ */ jsx3("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ jsx3(Icon, { name: "close", size: 17 }) }) : null
|
|
875
|
+
] }),
|
|
876
|
+
children !== void 0 ? /* @__PURE__ */ jsx3("div", { className: "sia-modal__body", style: height !== void 0 ? { flex: 1, minHeight: 0, overflow: "auto" } : void 0, children }) : null,
|
|
877
|
+
footer !== null ? /* @__PURE__ */ jsxs3("div", { className: "sia-modal__footer", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
878
|
+
footer === void 0 && footerExtra != null ? /* @__PURE__ */ jsx3("div", { style: { marginRight: "auto" }, children: footerExtra }) : null,
|
|
879
|
+
footer ?? defaultFooter
|
|
880
|
+
] }) : null
|
|
881
|
+
]
|
|
882
|
+
}
|
|
883
|
+
)
|
|
884
|
+
}
|
|
885
|
+
) });
|
|
886
|
+
});
|
|
887
|
+
function openModal(config) {
|
|
888
|
+
if (typeof document === "undefined") return { destroy() {
|
|
889
|
+
}, update() {
|
|
890
|
+
} };
|
|
891
|
+
const container = document.createElement("div");
|
|
892
|
+
container.className = "sia-modal-api-host";
|
|
893
|
+
document.body.appendChild(container);
|
|
894
|
+
const root = createRoot(container);
|
|
895
|
+
let currentConfig = config;
|
|
896
|
+
let currentOpen = true;
|
|
897
|
+
let destroyed = false;
|
|
898
|
+
let cleanupTimer;
|
|
899
|
+
function cleanup2() {
|
|
900
|
+
if (destroyed) return;
|
|
901
|
+
destroyed = true;
|
|
902
|
+
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
903
|
+
root.unmount();
|
|
904
|
+
container.remove();
|
|
905
|
+
modalHandles.delete(handle);
|
|
906
|
+
}
|
|
907
|
+
function closeWithMotion() {
|
|
908
|
+
if (destroyed || !currentOpen) return;
|
|
909
|
+
currentOpen = false;
|
|
910
|
+
render();
|
|
911
|
+
cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
|
|
912
|
+
}
|
|
913
|
+
function render() {
|
|
914
|
+
root.render(/* @__PURE__ */ jsx3(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
915
|
+
currentConfig.onOpenChange?.(nextOpen);
|
|
916
|
+
if (!nextOpen) closeWithMotion();
|
|
917
|
+
} }));
|
|
918
|
+
}
|
|
919
|
+
const handle = {
|
|
920
|
+
destroy: closeWithMotion,
|
|
921
|
+
update(next) {
|
|
922
|
+
if (destroyed) return;
|
|
923
|
+
currentConfig = { ...currentConfig, ...next };
|
|
924
|
+
render();
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
modalHandles.add(handle);
|
|
928
|
+
render();
|
|
929
|
+
return handle;
|
|
930
|
+
}
|
|
931
|
+
function preset(type, defaults = {}) {
|
|
932
|
+
return (config) => openModal({
|
|
933
|
+
okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
|
|
934
|
+
showCancel: type === "confirm",
|
|
935
|
+
closable: type !== "confirm",
|
|
936
|
+
maskClosable: type !== "confirm",
|
|
937
|
+
...defaults,
|
|
938
|
+
...config,
|
|
939
|
+
type
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
var Modal2 = Object.assign(ModalRoot, {
|
|
943
|
+
/** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
|
|
944
|
+
open: openModal,
|
|
945
|
+
/** 显示普通信息提示。 */
|
|
946
|
+
info: preset("info", { title: "\u63D0\u793A" }),
|
|
947
|
+
/** 显示成功提示。 */
|
|
948
|
+
success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
|
|
949
|
+
/** 显示警告提示。 */
|
|
950
|
+
warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
|
|
951
|
+
/** 显示错误提示。 */
|
|
952
|
+
error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
|
|
953
|
+
/** 打开确认弹框,支持异步确认;返回 false 可阻止关闭。 */
|
|
954
|
+
confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
|
|
955
|
+
/** 关闭由此 API 打开的所有弹层。 */
|
|
956
|
+
destroyAll() {
|
|
957
|
+
[...modalHandles].forEach((handle) => handle.destroy());
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
962
|
+
import { useEffect as useEffect6 } from "react";
|
|
963
|
+
|
|
964
|
+
// src/components/useScrollbarProximity.ts
|
|
965
|
+
import { useEffect as useEffect5 } from "react";
|
|
966
|
+
var users = 0;
|
|
967
|
+
var cleanup;
|
|
968
|
+
function useScrollbarProximity() {
|
|
969
|
+
useEffect5(() => {
|
|
970
|
+
if (users++ === 0) {
|
|
971
|
+
let frame = 0;
|
|
972
|
+
let x = -Infinity;
|
|
973
|
+
let y = -Infinity;
|
|
974
|
+
const nearby = /* @__PURE__ */ new Set();
|
|
975
|
+
const clear = () => {
|
|
976
|
+
nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
|
|
977
|
+
nearby.clear();
|
|
978
|
+
};
|
|
979
|
+
const update = () => {
|
|
980
|
+
frame = 0;
|
|
981
|
+
const next = /* @__PURE__ */ new Set();
|
|
982
|
+
document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
|
|
983
|
+
const rect = track.getBoundingClientRect();
|
|
984
|
+
const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
|
|
985
|
+
if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
|
|
986
|
+
next.add(track);
|
|
987
|
+
if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
nearby.forEach((track) => {
|
|
991
|
+
if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
|
|
992
|
+
});
|
|
993
|
+
nearby.clear();
|
|
994
|
+
next.forEach((track) => nearby.add(track));
|
|
995
|
+
};
|
|
996
|
+
const move = (event) => {
|
|
997
|
+
if (event.pointerType === "touch") return;
|
|
998
|
+
x = event.clientX;
|
|
999
|
+
y = event.clientY;
|
|
1000
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
1001
|
+
};
|
|
1002
|
+
const leave = () => {
|
|
1003
|
+
x = y = -Infinity;
|
|
1004
|
+
clear();
|
|
1005
|
+
};
|
|
1006
|
+
document.addEventListener("pointermove", move, { passive: true });
|
|
1007
|
+
document.documentElement.addEventListener("pointerleave", leave);
|
|
1008
|
+
window.addEventListener("blur", leave);
|
|
1009
|
+
cleanup = () => {
|
|
1010
|
+
if (frame) cancelAnimationFrame(frame);
|
|
1011
|
+
document.removeEventListener("pointermove", move);
|
|
1012
|
+
document.documentElement.removeEventListener("pointerleave", leave);
|
|
1013
|
+
window.removeEventListener("blur", leave);
|
|
1014
|
+
clear();
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
return () => {
|
|
1018
|
+
if (--users === 0) {
|
|
1019
|
+
cleanup?.();
|
|
1020
|
+
cleanup = void 0;
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
}, []);
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
1027
|
+
var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
1028
|
+
var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
|
|
1029
|
+
function isRootScroller(target) {
|
|
1030
|
+
return target === document.scrollingElement || target === document.documentElement;
|
|
1031
|
+
}
|
|
1032
|
+
function canScroll(target, axis) {
|
|
1033
|
+
if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
|
|
1034
|
+
if (isRootScroller(target)) {
|
|
1035
|
+
return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
1036
|
+
}
|
|
1037
|
+
const style = getComputedStyle(target);
|
|
1038
|
+
const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
|
|
1039
|
+
const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
1040
|
+
return hasOverflow && scrollableOverflow.has(overflow);
|
|
1041
|
+
}
|
|
1042
|
+
function visibleRect(target) {
|
|
1043
|
+
if (isRootScroller(target)) {
|
|
1044
|
+
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
1045
|
+
}
|
|
1046
|
+
const ownRect = target.getBoundingClientRect();
|
|
1047
|
+
let top = Math.max(0, ownRect.top);
|
|
1048
|
+
let right = Math.min(window.innerWidth, ownRect.right);
|
|
1049
|
+
let bottom = Math.min(window.innerHeight, ownRect.bottom);
|
|
1050
|
+
let left = Math.max(0, ownRect.left);
|
|
1051
|
+
let parent = target.parentElement;
|
|
1052
|
+
while (parent && parent !== document.body && parent !== document.documentElement) {
|
|
1053
|
+
const style = getComputedStyle(parent);
|
|
1054
|
+
const clipX = clippingOverflow.has(style.overflowX);
|
|
1055
|
+
const clipY = clippingOverflow.has(style.overflowY);
|
|
1056
|
+
if (clipX || clipY) {
|
|
1057
|
+
const rect = parent.getBoundingClientRect();
|
|
1058
|
+
if (clipX) {
|
|
1059
|
+
left = Math.max(left, rect.left);
|
|
1060
|
+
right = Math.min(right, rect.right);
|
|
1061
|
+
}
|
|
1062
|
+
if (clipY) {
|
|
1063
|
+
top = Math.max(top, rect.top);
|
|
1064
|
+
bottom = Math.min(bottom, rect.bottom);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
parent = parent.parentElement;
|
|
1068
|
+
}
|
|
1069
|
+
return {
|
|
1070
|
+
top,
|
|
1071
|
+
right,
|
|
1072
|
+
bottom,
|
|
1073
|
+
left,
|
|
1074
|
+
width: Math.max(0, right - left),
|
|
1075
|
+
height: Math.max(0, bottom - top)
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
function createTrack(axis) {
|
|
1079
|
+
const track = document.createElement("div");
|
|
1080
|
+
const thumb = document.createElement("div");
|
|
1081
|
+
track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
|
|
1082
|
+
thumb.className = "sia-floating-scrollbar__thumb";
|
|
1083
|
+
track.dataset.axis = axis;
|
|
1084
|
+
track.setAttribute("aria-hidden", "true");
|
|
1085
|
+
track.append(thumb);
|
|
1086
|
+
return { track, thumb };
|
|
1087
|
+
}
|
|
1088
|
+
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
1089
|
+
useScrollbarProximity();
|
|
1090
|
+
useEffect6(() => {
|
|
1091
|
+
if (disabled) return;
|
|
1092
|
+
const layer = document.createElement("div");
|
|
1093
|
+
layer.className = "sia-floating-scrollbar-layer";
|
|
1094
|
+
layer.setAttribute("aria-hidden", "true");
|
|
1095
|
+
document.body.append(layer);
|
|
1096
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1097
|
+
let scanFrame = 0;
|
|
1098
|
+
let updateFrame = 0;
|
|
1099
|
+
const setEntryVisible = (entry, visible) => {
|
|
1100
|
+
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
1101
|
+
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
1102
|
+
};
|
|
1103
|
+
const showEntry = (entry) => {
|
|
1104
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1105
|
+
entry.hideTimer = null;
|
|
1106
|
+
setEntryVisible(entry, true);
|
|
1107
|
+
};
|
|
1108
|
+
const scheduleHide = (entry, delay = 500) => {
|
|
1109
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1110
|
+
entry.hideTimer = window.setTimeout(() => {
|
|
1111
|
+
entry.hideTimer = null;
|
|
1112
|
+
if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
|
|
1113
|
+
}, delay);
|
|
1114
|
+
};
|
|
1115
|
+
const updateEntry = (entry) => {
|
|
1116
|
+
const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
|
|
1117
|
+
const hasHorizontal = canScroll(target, "horizontal");
|
|
1118
|
+
const hasVertical = canScroll(target, "vertical");
|
|
1119
|
+
const rect = visibleRect(target);
|
|
1120
|
+
const thickness = 10;
|
|
1121
|
+
horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
|
|
1122
|
+
verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
|
|
1123
|
+
if (!horizontalTrack.hidden) {
|
|
1124
|
+
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
1125
|
+
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
1126
|
+
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
1127
|
+
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
1128
|
+
horizontalTrack.style.left = `${rect.left}px`;
|
|
1129
|
+
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
1130
|
+
horizontalTrack.style.width = `${trackWidth}px`;
|
|
1131
|
+
horizontalTrack.style.height = `${thickness}px`;
|
|
1132
|
+
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
1133
|
+
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
1134
|
+
}
|
|
1135
|
+
if (!verticalTrack.hidden) {
|
|
1136
|
+
const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
|
|
1137
|
+
const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
|
|
1138
|
+
const travel = Math.max(0, trackHeight - thumbHeight);
|
|
1139
|
+
const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
|
|
1140
|
+
verticalTrack.style.left = `${rect.right - thickness}px`;
|
|
1141
|
+
verticalTrack.style.top = `${rect.top}px`;
|
|
1142
|
+
verticalTrack.style.width = `${thickness}px`;
|
|
1143
|
+
verticalTrack.style.height = `${trackHeight}px`;
|
|
1144
|
+
verticalThumb.style.height = `${thumbHeight}px`;
|
|
1145
|
+
verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
const scheduleUpdateAll = () => {
|
|
1149
|
+
if (updateFrame) return;
|
|
1150
|
+
updateFrame = window.requestAnimationFrame(() => {
|
|
1151
|
+
updateFrame = 0;
|
|
1152
|
+
entries.forEach(updateEntry);
|
|
1153
|
+
});
|
|
1154
|
+
};
|
|
1155
|
+
const bindTrackDrag = (entry, axis, track, thumb) => {
|
|
1156
|
+
const target = entry.target;
|
|
1157
|
+
const onTrackPointerEnter = () => {
|
|
1158
|
+
entry.hoveringTrack = true;
|
|
1159
|
+
showEntry(entry);
|
|
1160
|
+
};
|
|
1161
|
+
const onTrackPointerLeave = () => {
|
|
1162
|
+
entry.hoveringTrack = false;
|
|
1163
|
+
scheduleHide(entry);
|
|
1164
|
+
};
|
|
1165
|
+
const onTrackPointerDown = (event) => {
|
|
1166
|
+
if (event.target === thumb || event.button !== 0) return;
|
|
1167
|
+
event.preventDefault();
|
|
1168
|
+
event.stopPropagation();
|
|
1169
|
+
const trackRect = track.getBoundingClientRect();
|
|
1170
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
1171
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
1172
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
1173
|
+
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
1174
|
+
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
1175
|
+
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
1176
|
+
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
1177
|
+
};
|
|
1178
|
+
const onThumbPointerDown = (event) => {
|
|
1179
|
+
if (event.button !== 0) return;
|
|
1180
|
+
event.preventDefault();
|
|
1181
|
+
event.stopPropagation();
|
|
1182
|
+
entry.dragging = true;
|
|
1183
|
+
showEntry(entry);
|
|
1184
|
+
thumb.setPointerCapture(event.pointerId);
|
|
1185
|
+
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
1186
|
+
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
1187
|
+
const trackRect = track.getBoundingClientRect();
|
|
1188
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
1189
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
1190
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
1191
|
+
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
1192
|
+
const travel = Math.max(1, trackLength - thumbLength);
|
|
1193
|
+
const onPointerMove = (moveEvent) => {
|
|
1194
|
+
if (moveEvent.pointerId !== event.pointerId) return;
|
|
1195
|
+
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
1196
|
+
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
1197
|
+
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
1198
|
+
else target.scrollLeft = nextScroll;
|
|
1199
|
+
};
|
|
1200
|
+
const onPointerUp = (upEvent) => {
|
|
1201
|
+
if (upEvent.pointerId !== event.pointerId) return;
|
|
1202
|
+
entry.dragging = false;
|
|
1203
|
+
thumb.releasePointerCapture(event.pointerId);
|
|
1204
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
1205
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
1206
|
+
window.removeEventListener("pointercancel", onPointerUp);
|
|
1207
|
+
scheduleHide(entry);
|
|
1208
|
+
};
|
|
1209
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
1210
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
1211
|
+
window.addEventListener("pointercancel", onPointerUp);
|
|
1212
|
+
};
|
|
1213
|
+
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
1214
|
+
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
1215
|
+
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
1216
|
+
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
1217
|
+
return () => {
|
|
1218
|
+
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
1219
|
+
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
1220
|
+
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
1221
|
+
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
1222
|
+
};
|
|
1223
|
+
};
|
|
1224
|
+
const resizeObserver = new ResizeObserver((observedEntries) => {
|
|
1225
|
+
observedEntries.forEach(({ target }) => {
|
|
1226
|
+
const entry = entries.get(target);
|
|
1227
|
+
if (entry) updateEntry(entry);
|
|
1228
|
+
});
|
|
1229
|
+
});
|
|
1230
|
+
const addTarget = (target) => {
|
|
1231
|
+
if (entries.has(target)) return;
|
|
1232
|
+
const horizontal = createTrack("horizontal");
|
|
1233
|
+
const vertical = createTrack("vertical");
|
|
1234
|
+
layer.append(horizontal.track, vertical.track);
|
|
1235
|
+
const onPointerEnter = () => {
|
|
1236
|
+
const entry2 = entries.get(target);
|
|
1237
|
+
if (!entry2) return;
|
|
1238
|
+
entry2.hoveringTarget = true;
|
|
1239
|
+
showEntry(entry2);
|
|
1240
|
+
};
|
|
1241
|
+
const onPointerLeave = () => {
|
|
1242
|
+
const entry2 = entries.get(target);
|
|
1243
|
+
if (!entry2) return;
|
|
1244
|
+
entry2.hoveringTarget = false;
|
|
1245
|
+
scheduleHide(entry2);
|
|
1246
|
+
};
|
|
1247
|
+
const onScroll = () => {
|
|
1248
|
+
const entry2 = entries.get(target);
|
|
1249
|
+
if (!entry2) return;
|
|
1250
|
+
updateEntry(entry2);
|
|
1251
|
+
showEntry(entry2);
|
|
1252
|
+
scheduleHide(entry2, 700);
|
|
1253
|
+
};
|
|
1254
|
+
target.addEventListener("pointerenter", onPointerEnter);
|
|
1255
|
+
target.addEventListener("pointerleave", onPointerLeave);
|
|
1256
|
+
target.addEventListener("scroll", onScroll, { passive: true });
|
|
1257
|
+
const entry = {
|
|
1258
|
+
target,
|
|
1259
|
+
horizontalTrack: horizontal.track,
|
|
1260
|
+
horizontalThumb: horizontal.thumb,
|
|
1261
|
+
verticalTrack: vertical.track,
|
|
1262
|
+
verticalThumb: vertical.thumb,
|
|
1263
|
+
hideTimer: null,
|
|
1264
|
+
hoveringTarget: target.matches(":hover"),
|
|
1265
|
+
hoveringTrack: false,
|
|
1266
|
+
dragging: false,
|
|
1267
|
+
cleanup: () => void 0
|
|
1268
|
+
};
|
|
1269
|
+
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
1270
|
+
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
1271
|
+
entry.cleanup = () => {
|
|
1272
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1273
|
+
cleanupHorizontal();
|
|
1274
|
+
cleanupVertical();
|
|
1275
|
+
target.removeEventListener("pointerenter", onPointerEnter);
|
|
1276
|
+
target.removeEventListener("pointerleave", onPointerLeave);
|
|
1277
|
+
target.removeEventListener("scroll", onScroll);
|
|
1278
|
+
resizeObserver.unobserve(target);
|
|
1279
|
+
target.removeAttribute("data-sia-floating-scrollbar");
|
|
1280
|
+
horizontal.track.remove();
|
|
1281
|
+
vertical.track.remove();
|
|
1282
|
+
};
|
|
1283
|
+
entries.set(target, entry);
|
|
1284
|
+
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
1285
|
+
resizeObserver.observe(target);
|
|
1286
|
+
updateEntry(entry);
|
|
1287
|
+
if (entry.hoveringTarget) showEntry(entry);
|
|
1288
|
+
};
|
|
1289
|
+
const removeTarget = (target) => {
|
|
1290
|
+
const entry = entries.get(target);
|
|
1291
|
+
if (!entry) return;
|
|
1292
|
+
entry.cleanup();
|
|
1293
|
+
entries.delete(target);
|
|
1294
|
+
};
|
|
1295
|
+
const scanTargets = () => {
|
|
1296
|
+
scanFrame = 0;
|
|
1297
|
+
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
1298
|
+
const nextTargets = /* @__PURE__ */ new Set();
|
|
1299
|
+
candidates.forEach((target) => {
|
|
1300
|
+
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
1301
|
+
nextTargets.add(target);
|
|
1302
|
+
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
1303
|
+
}
|
|
1304
|
+
});
|
|
1305
|
+
entries.forEach((_entry, target) => {
|
|
1306
|
+
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
1307
|
+
else updateEntry(_entry);
|
|
1308
|
+
});
|
|
1309
|
+
};
|
|
1310
|
+
const scheduleScan = () => {
|
|
1311
|
+
if (scanFrame) return;
|
|
1312
|
+
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
1313
|
+
};
|
|
1314
|
+
const mutationObserver = new MutationObserver((mutations) => {
|
|
1315
|
+
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
1316
|
+
});
|
|
1317
|
+
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
1318
|
+
window.addEventListener("resize", scheduleScan);
|
|
1319
|
+
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
1320
|
+
scheduleScan();
|
|
1321
|
+
return () => {
|
|
1322
|
+
mutationObserver.disconnect();
|
|
1323
|
+
resizeObserver.disconnect();
|
|
1324
|
+
window.removeEventListener("resize", scheduleScan);
|
|
1325
|
+
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
1326
|
+
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
1327
|
+
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
1328
|
+
entries.forEach((entry) => entry.cleanup());
|
|
1329
|
+
entries.clear();
|
|
1330
|
+
layer.remove();
|
|
1054
1331
|
};
|
|
1055
|
-
}, [
|
|
1056
|
-
|
|
1057
|
-
function OverlayPortal({ children, container }) {
|
|
1058
|
-
if (typeof document === "undefined") return null;
|
|
1059
|
-
const target = typeof container === "function" ? container() : container ?? document.body;
|
|
1060
|
-
return createPortal2(children, target);
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
// src/components/Modal.tsx
|
|
1064
|
-
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1065
|
-
var modalHandles = /* @__PURE__ */ new Set();
|
|
1066
|
-
var MODAL_MOTION_DURATION = 220;
|
|
1067
|
-
var typeIcons = {
|
|
1068
|
-
info: /* @__PURE__ */ jsx3(Icon, { name: "info", size: 23 }),
|
|
1069
|
-
success: /* @__PURE__ */ jsx3(Icon, { name: "circle-check", size: 23 }),
|
|
1070
|
-
warning: /* @__PURE__ */ jsx3(Icon, { name: "warning", size: 23 }),
|
|
1071
|
-
error: /* @__PURE__ */ jsx3(Icon, { name: "circle-close", size: 23 }),
|
|
1072
|
-
confirm: /* @__PURE__ */ jsx3(Icon, { name: "question", size: 23 })
|
|
1073
|
-
};
|
|
1074
|
-
var ModalRoot = forwardRef2(function Modal({
|
|
1075
|
-
open,
|
|
1076
|
-
title,
|
|
1077
|
-
children,
|
|
1078
|
-
footer,
|
|
1079
|
-
footerExtra,
|
|
1080
|
-
type = "default",
|
|
1081
|
-
okText = "\u786E\u5B9A",
|
|
1082
|
-
cancelText = "\u53D6\u6D88",
|
|
1083
|
-
showCancel = type === "default" || type === "confirm",
|
|
1084
|
-
confirmLoading = false,
|
|
1085
|
-
okButtonProps,
|
|
1086
|
-
cancelButtonProps,
|
|
1087
|
-
closable = true,
|
|
1088
|
-
maskClosable = true,
|
|
1089
|
-
keyboard = true,
|
|
1090
|
-
centered = false,
|
|
1091
|
-
width = 520,
|
|
1092
|
-
height,
|
|
1093
|
-
zIndex = 1e3,
|
|
1094
|
-
getContainer,
|
|
1095
|
-
onOk,
|
|
1096
|
-
onCancel,
|
|
1097
|
-
onOpenChange,
|
|
1098
|
-
afterOpenChange,
|
|
1099
|
-
className = "",
|
|
1100
|
-
style,
|
|
1101
|
-
...props
|
|
1102
|
-
}, forwardedRef) {
|
|
1103
|
-
const localRef = useRef4(null);
|
|
1104
|
-
const titleId = useId3();
|
|
1105
|
-
const [submitting, setSubmitting] = useState2(false);
|
|
1106
|
-
const [rendered, setRendered] = useState2(open);
|
|
1107
|
-
const [closing, setClosing] = useState2(false);
|
|
1108
|
-
const afterOpenChangeRef = useRef4(afterOpenChange);
|
|
1109
|
-
afterOpenChangeRef.current = afterOpenChange;
|
|
1110
|
-
const submitLock = useRef4(false);
|
|
1111
|
-
useEffect6(() => {
|
|
1112
|
-
if (!open || !rendered) return void 0;
|
|
1113
|
-
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
1114
|
-
return () => window.clearTimeout(timer);
|
|
1115
|
-
}, [open, rendered]);
|
|
1116
|
-
useEffect6(() => {
|
|
1117
|
-
if (open) {
|
|
1118
|
-
setRendered(true);
|
|
1119
|
-
setClosing(false);
|
|
1120
|
-
return void 0;
|
|
1121
|
-
}
|
|
1122
|
-
if (!rendered) return void 0;
|
|
1123
|
-
setClosing(true);
|
|
1124
|
-
const timer = window.setTimeout(() => {
|
|
1125
|
-
setRendered(false);
|
|
1126
|
-
setClosing(false);
|
|
1127
|
-
afterOpenChangeRef.current?.(false);
|
|
1128
|
-
}, MODAL_MOTION_DURATION);
|
|
1129
|
-
return () => window.clearTimeout(timer);
|
|
1130
|
-
}, [open, rendered]);
|
|
1131
|
-
function setRef(node) {
|
|
1132
|
-
localRef.current = node;
|
|
1133
|
-
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
1134
|
-
else if (forwardedRef) forwardedRef.current = node;
|
|
1135
|
-
}
|
|
1136
|
-
function requestClose() {
|
|
1137
|
-
if (submitting || confirmLoading) return;
|
|
1138
|
-
onCancel?.();
|
|
1139
|
-
onOpenChange?.(false);
|
|
1140
|
-
}
|
|
1141
|
-
async function handleOk() {
|
|
1142
|
-
if (submitLock.current || confirmLoading) return;
|
|
1143
|
-
submitLock.current = true;
|
|
1144
|
-
if (!onOk) {
|
|
1145
|
-
onOpenChange?.(false);
|
|
1146
|
-
submitLock.current = false;
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
try {
|
|
1150
|
-
const result = onOk();
|
|
1151
|
-
if (result instanceof Promise) {
|
|
1152
|
-
setSubmitting(true);
|
|
1153
|
-
const resolved = await result;
|
|
1154
|
-
if (resolved !== false) onOpenChange?.(false);
|
|
1155
|
-
} else if (result !== false) {
|
|
1156
|
-
onOpenChange?.(false);
|
|
1157
|
-
}
|
|
1158
|
-
} catch {
|
|
1159
|
-
return;
|
|
1160
|
-
} finally {
|
|
1161
|
-
submitLock.current = false;
|
|
1162
|
-
setSubmitting(false);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
|
|
1166
|
-
if (!rendered) return null;
|
|
1167
|
-
const mergedStyle = {
|
|
1168
|
-
...height !== void 0 ? { display: "flex", flexDirection: "column", height, maxHeight: "calc(100dvh - 48px)" } : {},
|
|
1169
|
-
...style,
|
|
1170
|
-
"--sia-modal-width": typeof width === "number" ? `${width}px` : width
|
|
1171
|
-
};
|
|
1172
|
-
const loading = submitting || confirmLoading;
|
|
1173
|
-
const defaultFooter = /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
1174
|
-
showCancel ? /* @__PURE__ */ jsx3(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
|
|
1175
|
-
/* @__PURE__ */ jsx3(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
|
|
1176
|
-
] });
|
|
1177
|
-
return /* @__PURE__ */ jsx3(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ jsx3(
|
|
1178
|
-
"div",
|
|
1179
|
-
{
|
|
1180
|
-
className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
|
|
1181
|
-
"data-state": closing ? "closing" : "open",
|
|
1182
|
-
style: { zIndex },
|
|
1183
|
-
onMouseDown: (event) => {
|
|
1184
|
-
if (event.target === event.currentTarget && maskClosable) requestClose();
|
|
1185
|
-
},
|
|
1186
|
-
children: /* @__PURE__ */ jsxs3(
|
|
1187
|
-
"div",
|
|
1188
|
-
{
|
|
1189
|
-
ref: setRef,
|
|
1190
|
-
className: `sia-modal sia-modal--${type} ${className}`.trim(),
|
|
1191
|
-
style: mergedStyle,
|
|
1192
|
-
role: "dialog",
|
|
1193
|
-
"aria-modal": "true",
|
|
1194
|
-
"aria-labelledby": title ? titleId : void 0,
|
|
1195
|
-
tabIndex: -1,
|
|
1196
|
-
...withTitleTooltip(props),
|
|
1197
|
-
children: [
|
|
1198
|
-
/* @__PURE__ */ jsxs3("div", { className: "sia-modal__header", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
1199
|
-
/* @__PURE__ */ jsxs3("div", { className: "sia-modal__heading", children: [
|
|
1200
|
-
typeIcons[type] ? /* @__PURE__ */ jsx3("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
|
|
1201
|
-
title ? /* @__PURE__ */ jsx3("strong", { id: titleId, children: title }) : null
|
|
1202
|
-
] }),
|
|
1203
|
-
closable ? /* @__PURE__ */ jsx3("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ jsx3(Icon, { name: "close", size: 17 }) }) : null
|
|
1204
|
-
] }),
|
|
1205
|
-
children !== void 0 ? /* @__PURE__ */ jsx3("div", { className: "sia-modal__body", style: height !== void 0 ? { flex: 1, minHeight: 0, overflow: "auto" } : void 0, children }) : null,
|
|
1206
|
-
footer !== null ? /* @__PURE__ */ jsxs3("div", { className: "sia-modal__footer", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
1207
|
-
footer === void 0 && footerExtra != null ? /* @__PURE__ */ jsx3("div", { style: { marginRight: "auto" }, children: footerExtra }) : null,
|
|
1208
|
-
footer ?? defaultFooter
|
|
1209
|
-
] }) : null
|
|
1210
|
-
]
|
|
1211
|
-
}
|
|
1212
|
-
)
|
|
1213
|
-
}
|
|
1214
|
-
) });
|
|
1215
|
-
});
|
|
1216
|
-
function openModal(config) {
|
|
1217
|
-
if (typeof document === "undefined") return { destroy() {
|
|
1218
|
-
}, update() {
|
|
1219
|
-
} };
|
|
1220
|
-
const container = document.createElement("div");
|
|
1221
|
-
container.className = "sia-modal-api-host";
|
|
1222
|
-
document.body.appendChild(container);
|
|
1223
|
-
const root = createRoot(container);
|
|
1224
|
-
let currentConfig = config;
|
|
1225
|
-
let currentOpen = true;
|
|
1226
|
-
let destroyed = false;
|
|
1227
|
-
let cleanupTimer;
|
|
1228
|
-
function cleanup2() {
|
|
1229
|
-
if (destroyed) return;
|
|
1230
|
-
destroyed = true;
|
|
1231
|
-
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
1232
|
-
root.unmount();
|
|
1233
|
-
container.remove();
|
|
1234
|
-
modalHandles.delete(handle);
|
|
1235
|
-
}
|
|
1236
|
-
function closeWithMotion() {
|
|
1237
|
-
if (destroyed || !currentOpen) return;
|
|
1238
|
-
currentOpen = false;
|
|
1239
|
-
render();
|
|
1240
|
-
cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
|
|
1241
|
-
}
|
|
1242
|
-
function render() {
|
|
1243
|
-
root.render(/* @__PURE__ */ jsx3(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
1244
|
-
currentConfig.onOpenChange?.(nextOpen);
|
|
1245
|
-
if (!nextOpen) closeWithMotion();
|
|
1246
|
-
} }));
|
|
1247
|
-
}
|
|
1248
|
-
const handle = {
|
|
1249
|
-
destroy: closeWithMotion,
|
|
1250
|
-
update(next) {
|
|
1251
|
-
if (destroyed) return;
|
|
1252
|
-
currentConfig = { ...currentConfig, ...next };
|
|
1253
|
-
render();
|
|
1254
|
-
}
|
|
1255
|
-
};
|
|
1256
|
-
modalHandles.add(handle);
|
|
1257
|
-
render();
|
|
1258
|
-
return handle;
|
|
1259
|
-
}
|
|
1260
|
-
function preset(type, defaults = {}) {
|
|
1261
|
-
return (config) => openModal({
|
|
1262
|
-
okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
|
|
1263
|
-
showCancel: type === "confirm",
|
|
1264
|
-
closable: type !== "confirm",
|
|
1265
|
-
maskClosable: type !== "confirm",
|
|
1266
|
-
...defaults,
|
|
1267
|
-
...config,
|
|
1268
|
-
type
|
|
1269
|
-
});
|
|
1332
|
+
}, [disabled, targetRef]);
|
|
1333
|
+
return null;
|
|
1270
1334
|
}
|
|
1271
|
-
var Modal2 = Object.assign(ModalRoot, {
|
|
1272
|
-
/** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
|
|
1273
|
-
open: openModal,
|
|
1274
|
-
/** 显示普通信息提示。 */
|
|
1275
|
-
info: preset("info", { title: "\u63D0\u793A" }),
|
|
1276
|
-
/** 显示成功提示。 */
|
|
1277
|
-
success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
|
|
1278
|
-
/** 显示警告提示。 */
|
|
1279
|
-
warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
|
|
1280
|
-
/** 显示错误提示。 */
|
|
1281
|
-
error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
|
|
1282
|
-
/** 打开确认弹框,支持异步确认;返回 false 可阻止关闭。 */
|
|
1283
|
-
confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
|
|
1284
|
-
/** 关闭由此 API 打开的所有弹层。 */
|
|
1285
|
-
destroyAll() {
|
|
1286
|
-
[...modalHandles].forEach((handle) => handle.destroy());
|
|
1287
|
-
}
|
|
1288
|
-
});
|
|
1289
1335
|
|
|
1290
1336
|
// src/components/SelectionPanel.tsx
|
|
1291
1337
|
import { useEffect as useEffect7, useId as useId4, useMemo as useMemo3, useRef as useRef5, useState as useState3 } from "react";
|
|
@@ -2006,8 +2052,6 @@ var Select = forwardRef3(function Select2({
|
|
|
2006
2052
|
});
|
|
2007
2053
|
|
|
2008
2054
|
export {
|
|
2009
|
-
useScrollbarProximity,
|
|
2010
|
-
FloatingScrollbarProvider,
|
|
2011
2055
|
Checkbox2 as Checkbox,
|
|
2012
2056
|
Tooltip,
|
|
2013
2057
|
Popover,
|
|
@@ -2016,6 +2060,8 @@ export {
|
|
|
2016
2060
|
useOverlayLifecycle,
|
|
2017
2061
|
OverlayPortal,
|
|
2018
2062
|
Modal2 as Modal,
|
|
2063
|
+
useScrollbarProximity,
|
|
2064
|
+
FloatingScrollbarProvider,
|
|
2019
2065
|
SelectionPanel,
|
|
2020
2066
|
OverflowTags,
|
|
2021
2067
|
Select
|