@sia.soul/sia-react-ui 0.1.25 → 0.1.26
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/{Select-O_yY51vc.d.ts → Select-CCrPqULn.d.ts} +1 -1
- package/dist/{Select-W_xpkpOW.d.cts → Select-YJbT-MF1.d.cts} +1 -1
- package/dist/{chunk-QCBKT5FV.js → chunk-5MW3NE2V.js} +225 -200
- package/dist/{chunk-IYO2JSGQ.js → chunk-IQU4GGLM.js} +10 -4
- package/dist/{chunk-RWODH2LW.js → chunk-LK56NX5F.js} +1 -1
- package/dist/{chunk-W52CNNWW.js → chunk-NAOV53NK.js} +2 -2
- package/dist/{chunk-27ZYAKII.js → chunk-YF2I6SDB.js} +1 -1
- package/dist/{core-tbb9ZiBY.d.cts → core-BM-wnJRa.d.cts} +3 -3
- package/dist/{core-BOzLwiXG.d.ts → core-CLqv6btD.d.ts} +3 -3
- package/dist/core.cjs +269 -242
- package/dist/core.css +10 -6
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +3 -3
- package/dist/index.cjs +279 -249
- package/dist/index.css +10 -6
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +8 -8
- package/dist/rich-text-editor.cjs +1 -1
- package/dist/rich-text-editor.js +2 -2
- package/dist/{select-date-range-C9w8z3G8.d.cts → select-date-range-CtA-B8DB.d.cts} +1 -1
- package/dist/{select-date-range-BjqFUeU6.d.ts → select-date-range-D9W_mmMq.d.ts} +1 -1
- package/dist/select-date-range.cjs +705 -673
- package/dist/select-date-range.d.cts +2 -2
- package/dist/select-date-range.d.ts +2 -2
- package/dist/select-date-range.js +3 -3
- package/package.json +1 -1
|
@@ -301,7 +301,7 @@ function useFloatingPlaceholder({ mode, placeholder, filled, active = false }) {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
// src/components/DatePicker.tsx
|
|
304
|
-
var
|
|
304
|
+
var import_react7 = require("react");
|
|
305
305
|
|
|
306
306
|
// src/components/Icon.tsx
|
|
307
307
|
var import_react3 = require("react");
|
|
@@ -1113,167 +1113,548 @@ var Icon = (0, import_react3.forwardRef)(function Icon2({ name, size = "1em", st
|
|
|
1113
1113
|
});
|
|
1114
1114
|
|
|
1115
1115
|
// src/components/DatePickerPanel.tsx
|
|
1116
|
+
var import_react6 = require("react");
|
|
1117
|
+
|
|
1118
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
1119
|
+
var import_react5 = require("react");
|
|
1120
|
+
|
|
1121
|
+
// src/components/useScrollbarProximity.ts
|
|
1116
1122
|
var import_react4 = require("react");
|
|
1117
|
-
var
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1123
|
+
var users = 0;
|
|
1124
|
+
var cleanup;
|
|
1125
|
+
function useScrollbarProximity() {
|
|
1126
|
+
(0, import_react4.useEffect)(() => {
|
|
1127
|
+
if (users++ === 0) {
|
|
1128
|
+
let frame = 0;
|
|
1129
|
+
let x = -Infinity;
|
|
1130
|
+
let y = -Infinity;
|
|
1131
|
+
const nearby = /* @__PURE__ */ new Set();
|
|
1132
|
+
const clear = () => {
|
|
1133
|
+
nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
|
|
1134
|
+
nearby.clear();
|
|
1135
|
+
};
|
|
1136
|
+
const update = () => {
|
|
1137
|
+
frame = 0;
|
|
1138
|
+
const next = /* @__PURE__ */ new Set();
|
|
1139
|
+
document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
|
|
1140
|
+
const rect = track.getBoundingClientRect();
|
|
1141
|
+
const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
|
|
1142
|
+
if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
|
|
1143
|
+
next.add(track);
|
|
1144
|
+
if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
1147
|
+
nearby.forEach((track) => {
|
|
1148
|
+
if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
|
|
1149
|
+
});
|
|
1150
|
+
nearby.clear();
|
|
1151
|
+
next.forEach((track) => nearby.add(track));
|
|
1152
|
+
};
|
|
1153
|
+
const move = (event) => {
|
|
1154
|
+
if (event.pointerType === "touch") return;
|
|
1155
|
+
x = event.clientX;
|
|
1156
|
+
y = event.clientY;
|
|
1157
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
1158
|
+
};
|
|
1159
|
+
const leave = () => {
|
|
1160
|
+
x = y = -Infinity;
|
|
1161
|
+
clear();
|
|
1162
|
+
};
|
|
1163
|
+
document.addEventListener("pointermove", move, { passive: true });
|
|
1164
|
+
document.documentElement.addEventListener("pointerleave", leave);
|
|
1165
|
+
window.addEventListener("blur", leave);
|
|
1166
|
+
cleanup = () => {
|
|
1167
|
+
if (frame) cancelAnimationFrame(frame);
|
|
1168
|
+
document.removeEventListener("pointermove", move);
|
|
1169
|
+
document.documentElement.removeEventListener("pointerleave", leave);
|
|
1170
|
+
window.removeEventListener("blur", leave);
|
|
1171
|
+
clear();
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
return () => {
|
|
1175
|
+
if (--users === 0) {
|
|
1176
|
+
cleanup?.();
|
|
1177
|
+
cleanup = void 0;
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
}, []);
|
|
1163
1181
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
disabledDate,
|
|
1171
|
-
onSelect,
|
|
1172
|
-
onHover
|
|
1173
|
-
}) {
|
|
1174
|
-
const first = startOfMonth(month);
|
|
1175
|
-
const mondayIndex = (first.getDay() + 6) % 7;
|
|
1176
|
-
const gridStart = addDays(first, -mondayIndex);
|
|
1177
|
-
const today = dateKey(/* @__PURE__ */ new Date());
|
|
1178
|
-
const start = range[0];
|
|
1179
|
-
const end = range[1] || previewEnd || "";
|
|
1180
|
-
const low = start && end ? start <= end ? start : end : "";
|
|
1181
|
-
const high = start && end ? start <= end ? end : start : "";
|
|
1182
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sia-date-panel__month", children: [
|
|
1183
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "sia-date-panel__weekdays", "aria-hidden": "true", children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: day }, day)) }),
|
|
1184
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "sia-date-panel__days", children: Array.from({ length: 42 }, (_, index) => {
|
|
1185
|
-
const date = addDays(gridStart, index);
|
|
1186
|
-
const key = dateKey(date);
|
|
1187
|
-
const outside = date.getMonth() !== month.getMonth();
|
|
1188
|
-
const disabled = disabledDate?.(key) ?? false;
|
|
1189
|
-
const selected = selectedDates.includes(key);
|
|
1190
|
-
const rangeStart = Boolean(start && key === start);
|
|
1191
|
-
const rangeEnd = Boolean(range[1] && key === range[1]);
|
|
1192
|
-
const inRange = Boolean(low && high && key >= low && key <= high);
|
|
1193
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1194
|
-
"span",
|
|
1195
|
-
{
|
|
1196
|
-
className: `sia-date-panel__cell${outside ? " is-outside" : ""}${selected ? " is-selected" : ""}${rangeStart ? " is-range-start" : ""}${rangeEnd ? " is-range-end" : ""}${inRange ? " is-in-range" : ""}${key === today ? " is-today" : ""}`,
|
|
1197
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1198
|
-
"button",
|
|
1199
|
-
{
|
|
1200
|
-
type: "button",
|
|
1201
|
-
"aria-label": key,
|
|
1202
|
-
"aria-pressed": selected || rangeStart || rangeEnd || void 0,
|
|
1203
|
-
disabled,
|
|
1204
|
-
onClick: () => onSelect(key),
|
|
1205
|
-
onMouseEnter: () => onHover?.(key),
|
|
1206
|
-
children: date.getDate()
|
|
1207
|
-
}
|
|
1208
|
-
)
|
|
1209
|
-
},
|
|
1210
|
-
key
|
|
1211
|
-
);
|
|
1212
|
-
}) })
|
|
1213
|
-
] });
|
|
1182
|
+
|
|
1183
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
1184
|
+
var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
1185
|
+
var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
|
|
1186
|
+
function isRootScroller(target) {
|
|
1187
|
+
return target === document.scrollingElement || target === document.documentElement;
|
|
1214
1188
|
}
|
|
1215
|
-
function
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sia-date-panel__header", children: [
|
|
1225
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "sia-date-panel__nav", children: [
|
|
1226
|
-
onPreviousYear ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "aria-label": "\u4E0A\u4E00\u5E74", onClick: onPreviousYear, children: [
|
|
1227
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-left", size: 13 }),
|
|
1228
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-left", size: 13 })
|
|
1229
|
-
] }) : null,
|
|
1230
|
-
onPreviousMonth ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": "\u4E0A\u4E2A\u6708", onClick: onPreviousMonth, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-left", size: 15 }) }) : null
|
|
1231
|
-
] }),
|
|
1232
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
|
|
1233
|
-
label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: label }) : null,
|
|
1234
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
1235
|
-
month.getFullYear(),
|
|
1236
|
-
"\u5E74\xA0 ",
|
|
1237
|
-
month.getMonth() + 1,
|
|
1238
|
-
"\u6708"
|
|
1239
|
-
] })
|
|
1240
|
-
] }),
|
|
1241
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "sia-date-panel__nav", children: [
|
|
1242
|
-
onNextMonth ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": "\u4E0B\u4E2A\u6708", onClick: onNextMonth, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-right", size: 15 }) }) : null,
|
|
1243
|
-
onNextYear ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "aria-label": "\u4E0B\u4E00\u5E74", onClick: onNextYear, children: [
|
|
1244
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-right", size: 13 }),
|
|
1245
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-right", size: 13 })
|
|
1246
|
-
] }) : null
|
|
1247
|
-
] }),
|
|
1248
|
-
range ? null : null
|
|
1249
|
-
] });
|
|
1189
|
+
function canScroll(target, axis) {
|
|
1190
|
+
if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
|
|
1191
|
+
if (isRootScroller(target)) {
|
|
1192
|
+
return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
1193
|
+
}
|
|
1194
|
+
const style = getComputedStyle(target);
|
|
1195
|
+
const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
|
|
1196
|
+
const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
1197
|
+
return hasOverflow && scrollableOverflow.has(overflow);
|
|
1250
1198
|
}
|
|
1251
|
-
function
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
(
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
const
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1199
|
+
function visibleRect(target) {
|
|
1200
|
+
if (isRootScroller(target)) {
|
|
1201
|
+
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
1202
|
+
}
|
|
1203
|
+
const ownRect = target.getBoundingClientRect();
|
|
1204
|
+
let top = Math.max(0, ownRect.top);
|
|
1205
|
+
let right = Math.min(window.innerWidth, ownRect.right);
|
|
1206
|
+
let bottom = Math.min(window.innerHeight, ownRect.bottom);
|
|
1207
|
+
let left = Math.max(0, ownRect.left);
|
|
1208
|
+
let parent = target.parentElement;
|
|
1209
|
+
while (parent && parent !== document.body && parent !== document.documentElement) {
|
|
1210
|
+
const style = getComputedStyle(parent);
|
|
1211
|
+
const clipX = clippingOverflow.has(style.overflowX);
|
|
1212
|
+
const clipY = clippingOverflow.has(style.overflowY);
|
|
1213
|
+
if (clipX || clipY) {
|
|
1214
|
+
const rect = parent.getBoundingClientRect();
|
|
1215
|
+
if (clipX) {
|
|
1216
|
+
left = Math.max(left, rect.left);
|
|
1217
|
+
right = Math.min(right, rect.right);
|
|
1218
|
+
}
|
|
1219
|
+
if (clipY) {
|
|
1220
|
+
top = Math.max(top, rect.top);
|
|
1221
|
+
bottom = Math.min(bottom, rect.bottom);
|
|
1270
1222
|
}
|
|
1271
1223
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1224
|
+
parent = parent.parentElement;
|
|
1225
|
+
}
|
|
1226
|
+
return {
|
|
1227
|
+
top,
|
|
1228
|
+
right,
|
|
1229
|
+
bottom,
|
|
1230
|
+
left,
|
|
1231
|
+
width: Math.max(0, right - left),
|
|
1232
|
+
height: Math.max(0, bottom - top)
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
function createTrack(axis) {
|
|
1236
|
+
const track = document.createElement("div");
|
|
1237
|
+
const thumb = document.createElement("div");
|
|
1238
|
+
track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
|
|
1239
|
+
thumb.className = "sia-floating-scrollbar__thumb";
|
|
1240
|
+
track.dataset.axis = axis;
|
|
1241
|
+
track.setAttribute("aria-hidden", "true");
|
|
1242
|
+
track.append(thumb);
|
|
1243
|
+
return { track, thumb };
|
|
1244
|
+
}
|
|
1245
|
+
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
1246
|
+
useScrollbarProximity();
|
|
1247
|
+
(0, import_react5.useEffect)(() => {
|
|
1248
|
+
if (disabled) return;
|
|
1249
|
+
const layer = document.createElement("div");
|
|
1250
|
+
layer.className = "sia-floating-scrollbar-layer";
|
|
1251
|
+
layer.setAttribute("aria-hidden", "true");
|
|
1252
|
+
document.body.append(layer);
|
|
1253
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1254
|
+
let scanFrame = 0;
|
|
1255
|
+
let updateFrame = 0;
|
|
1256
|
+
const setEntryVisible = (entry, visible) => {
|
|
1257
|
+
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
1258
|
+
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
1259
|
+
};
|
|
1260
|
+
const showEntry = (entry) => {
|
|
1261
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1262
|
+
entry.hideTimer = null;
|
|
1263
|
+
setEntryVisible(entry, true);
|
|
1264
|
+
};
|
|
1265
|
+
const scheduleHide = (entry, delay = 500) => {
|
|
1266
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1267
|
+
entry.hideTimer = window.setTimeout(() => {
|
|
1268
|
+
entry.hideTimer = null;
|
|
1269
|
+
if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
|
|
1270
|
+
}, delay);
|
|
1271
|
+
};
|
|
1272
|
+
const updateEntry = (entry) => {
|
|
1273
|
+
const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
|
|
1274
|
+
const hasHorizontal = canScroll(target, "horizontal");
|
|
1275
|
+
const hasVertical = canScroll(target, "vertical");
|
|
1276
|
+
const rect = visibleRect(target);
|
|
1277
|
+
const thickness = 10;
|
|
1278
|
+
horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
|
|
1279
|
+
verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
|
|
1280
|
+
if (!horizontalTrack.hidden) {
|
|
1281
|
+
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
1282
|
+
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
1283
|
+
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
1284
|
+
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
1285
|
+
horizontalTrack.style.left = `${rect.left}px`;
|
|
1286
|
+
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
1287
|
+
horizontalTrack.style.width = `${trackWidth}px`;
|
|
1288
|
+
horizontalTrack.style.height = `${thickness}px`;
|
|
1289
|
+
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
1290
|
+
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
1291
|
+
}
|
|
1292
|
+
if (!verticalTrack.hidden) {
|
|
1293
|
+
const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
|
|
1294
|
+
const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
|
|
1295
|
+
const travel = Math.max(0, trackHeight - thumbHeight);
|
|
1296
|
+
const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
|
|
1297
|
+
verticalTrack.style.left = `${rect.right - thickness}px`;
|
|
1298
|
+
verticalTrack.style.top = `${rect.top}px`;
|
|
1299
|
+
verticalTrack.style.width = `${thickness}px`;
|
|
1300
|
+
verticalTrack.style.height = `${trackHeight}px`;
|
|
1301
|
+
verticalThumb.style.height = `${thumbHeight}px`;
|
|
1302
|
+
verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
const scheduleUpdateAll = () => {
|
|
1306
|
+
if (updateFrame) return;
|
|
1307
|
+
updateFrame = window.requestAnimationFrame(() => {
|
|
1308
|
+
updateFrame = 0;
|
|
1309
|
+
entries.forEach(updateEntry);
|
|
1310
|
+
});
|
|
1311
|
+
};
|
|
1312
|
+
const bindTrackDrag = (entry, axis, track, thumb) => {
|
|
1313
|
+
const target = entry.target;
|
|
1314
|
+
const onTrackPointerEnter = () => {
|
|
1315
|
+
entry.hoveringTrack = true;
|
|
1316
|
+
showEntry(entry);
|
|
1317
|
+
};
|
|
1318
|
+
const onTrackPointerLeave = () => {
|
|
1319
|
+
entry.hoveringTrack = false;
|
|
1320
|
+
scheduleHide(entry);
|
|
1321
|
+
};
|
|
1322
|
+
const onTrackPointerDown = (event) => {
|
|
1323
|
+
if (event.target === thumb || event.button !== 0) return;
|
|
1324
|
+
event.preventDefault();
|
|
1325
|
+
event.stopPropagation();
|
|
1326
|
+
const trackRect = track.getBoundingClientRect();
|
|
1327
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
1328
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
1329
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
1330
|
+
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
1331
|
+
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
1332
|
+
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
1333
|
+
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
1334
|
+
};
|
|
1335
|
+
const onThumbPointerDown = (event) => {
|
|
1336
|
+
if (event.button !== 0) return;
|
|
1337
|
+
event.preventDefault();
|
|
1338
|
+
event.stopPropagation();
|
|
1339
|
+
entry.dragging = true;
|
|
1340
|
+
showEntry(entry);
|
|
1341
|
+
thumb.setPointerCapture(event.pointerId);
|
|
1342
|
+
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
1343
|
+
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
1344
|
+
const trackRect = track.getBoundingClientRect();
|
|
1345
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
1346
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
1347
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
1348
|
+
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
1349
|
+
const travel = Math.max(1, trackLength - thumbLength);
|
|
1350
|
+
const onPointerMove = (moveEvent) => {
|
|
1351
|
+
if (moveEvent.pointerId !== event.pointerId) return;
|
|
1352
|
+
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
1353
|
+
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
1354
|
+
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
1355
|
+
else target.scrollLeft = nextScroll;
|
|
1356
|
+
};
|
|
1357
|
+
const onPointerUp = (upEvent) => {
|
|
1358
|
+
if (upEvent.pointerId !== event.pointerId) return;
|
|
1359
|
+
entry.dragging = false;
|
|
1360
|
+
thumb.releasePointerCapture(event.pointerId);
|
|
1361
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
1362
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
1363
|
+
window.removeEventListener("pointercancel", onPointerUp);
|
|
1364
|
+
scheduleHide(entry);
|
|
1365
|
+
};
|
|
1366
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
1367
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
1368
|
+
window.addEventListener("pointercancel", onPointerUp);
|
|
1369
|
+
};
|
|
1370
|
+
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
1371
|
+
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
1372
|
+
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
1373
|
+
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
1374
|
+
return () => {
|
|
1375
|
+
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
1376
|
+
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
1377
|
+
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
1378
|
+
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
1379
|
+
};
|
|
1380
|
+
};
|
|
1381
|
+
const resizeObserver = new ResizeObserver((observedEntries) => {
|
|
1382
|
+
observedEntries.forEach(({ target }) => {
|
|
1383
|
+
const entry = entries.get(target);
|
|
1384
|
+
if (entry) updateEntry(entry);
|
|
1385
|
+
});
|
|
1386
|
+
});
|
|
1387
|
+
const addTarget = (target) => {
|
|
1388
|
+
if (entries.has(target)) return;
|
|
1389
|
+
const horizontal = createTrack("horizontal");
|
|
1390
|
+
const vertical = createTrack("vertical");
|
|
1391
|
+
layer.append(horizontal.track, vertical.track);
|
|
1392
|
+
const onPointerEnter = () => {
|
|
1393
|
+
const entry2 = entries.get(target);
|
|
1394
|
+
if (!entry2) return;
|
|
1395
|
+
entry2.hoveringTarget = true;
|
|
1396
|
+
showEntry(entry2);
|
|
1397
|
+
};
|
|
1398
|
+
const onPointerLeave = () => {
|
|
1399
|
+
const entry2 = entries.get(target);
|
|
1400
|
+
if (!entry2) return;
|
|
1401
|
+
entry2.hoveringTarget = false;
|
|
1402
|
+
scheduleHide(entry2);
|
|
1403
|
+
};
|
|
1404
|
+
const onScroll = () => {
|
|
1405
|
+
const entry2 = entries.get(target);
|
|
1406
|
+
if (!entry2) return;
|
|
1407
|
+
updateEntry(entry2);
|
|
1408
|
+
showEntry(entry2);
|
|
1409
|
+
scheduleHide(entry2, 700);
|
|
1410
|
+
};
|
|
1411
|
+
target.addEventListener("pointerenter", onPointerEnter);
|
|
1412
|
+
target.addEventListener("pointerleave", onPointerLeave);
|
|
1413
|
+
target.addEventListener("scroll", onScroll, { passive: true });
|
|
1414
|
+
const entry = {
|
|
1415
|
+
target,
|
|
1416
|
+
horizontalTrack: horizontal.track,
|
|
1417
|
+
horizontalThumb: horizontal.thumb,
|
|
1418
|
+
verticalTrack: vertical.track,
|
|
1419
|
+
verticalThumb: vertical.thumb,
|
|
1420
|
+
hideTimer: null,
|
|
1421
|
+
hoveringTarget: target.matches(":hover"),
|
|
1422
|
+
hoveringTrack: false,
|
|
1423
|
+
dragging: false,
|
|
1424
|
+
cleanup: () => void 0
|
|
1425
|
+
};
|
|
1426
|
+
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
1427
|
+
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
1428
|
+
entry.cleanup = () => {
|
|
1429
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
1430
|
+
cleanupHorizontal();
|
|
1431
|
+
cleanupVertical();
|
|
1432
|
+
target.removeEventListener("pointerenter", onPointerEnter);
|
|
1433
|
+
target.removeEventListener("pointerleave", onPointerLeave);
|
|
1434
|
+
target.removeEventListener("scroll", onScroll);
|
|
1435
|
+
resizeObserver.unobserve(target);
|
|
1436
|
+
target.removeAttribute("data-sia-floating-scrollbar");
|
|
1437
|
+
horizontal.track.remove();
|
|
1438
|
+
vertical.track.remove();
|
|
1439
|
+
};
|
|
1440
|
+
entries.set(target, entry);
|
|
1441
|
+
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
1442
|
+
resizeObserver.observe(target);
|
|
1443
|
+
updateEntry(entry);
|
|
1444
|
+
if (entry.hoveringTarget) showEntry(entry);
|
|
1445
|
+
};
|
|
1446
|
+
const removeTarget = (target) => {
|
|
1447
|
+
const entry = entries.get(target);
|
|
1448
|
+
if (!entry) return;
|
|
1449
|
+
entry.cleanup();
|
|
1450
|
+
entries.delete(target);
|
|
1451
|
+
};
|
|
1452
|
+
const scanTargets = () => {
|
|
1453
|
+
scanFrame = 0;
|
|
1454
|
+
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
1455
|
+
const nextTargets = /* @__PURE__ */ new Set();
|
|
1456
|
+
candidates.forEach((target) => {
|
|
1457
|
+
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
1458
|
+
nextTargets.add(target);
|
|
1459
|
+
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
entries.forEach((_entry, target) => {
|
|
1463
|
+
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
1464
|
+
else updateEntry(_entry);
|
|
1465
|
+
});
|
|
1466
|
+
};
|
|
1467
|
+
const scheduleScan = () => {
|
|
1468
|
+
if (scanFrame) return;
|
|
1469
|
+
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
1470
|
+
};
|
|
1471
|
+
const mutationObserver = new MutationObserver((mutations) => {
|
|
1472
|
+
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
1473
|
+
});
|
|
1474
|
+
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
1475
|
+
window.addEventListener("resize", scheduleScan);
|
|
1476
|
+
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
1477
|
+
scheduleScan();
|
|
1478
|
+
return () => {
|
|
1479
|
+
mutationObserver.disconnect();
|
|
1480
|
+
resizeObserver.disconnect();
|
|
1481
|
+
window.removeEventListener("resize", scheduleScan);
|
|
1482
|
+
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
1483
|
+
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
1484
|
+
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
1485
|
+
entries.forEach((entry) => entry.cleanup());
|
|
1486
|
+
entries.clear();
|
|
1487
|
+
layer.remove();
|
|
1488
|
+
};
|
|
1489
|
+
}, [disabled, targetRef]);
|
|
1490
|
+
return null;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
// src/components/DatePickerPanel.tsx
|
|
1494
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1495
|
+
function pad(value) {
|
|
1496
|
+
return String(value).padStart(2, "0");
|
|
1497
|
+
}
|
|
1498
|
+
function dateKey(date) {
|
|
1499
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
1500
|
+
}
|
|
1501
|
+
function parseDate(value) {
|
|
1502
|
+
const match = value?.match(/^(\d{4})-(\d{2})-(\d{2})/);
|
|
1503
|
+
if (!match) return null;
|
|
1504
|
+
const date = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
|
|
1505
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
1506
|
+
}
|
|
1507
|
+
function startOfMonth(value) {
|
|
1508
|
+
return new Date(value.getFullYear(), value.getMonth(), 1);
|
|
1509
|
+
}
|
|
1510
|
+
function addMonths(value, amount) {
|
|
1511
|
+
return new Date(value.getFullYear(), value.getMonth() + amount, 1);
|
|
1512
|
+
}
|
|
1513
|
+
function addDays(value, amount) {
|
|
1514
|
+
return new Date(value.getFullYear(), value.getMonth(), value.getDate() + amount);
|
|
1515
|
+
}
|
|
1516
|
+
function daysBetween(left, right) {
|
|
1517
|
+
const leftDate = parseDate(left);
|
|
1518
|
+
const rightDate = parseDate(right);
|
|
1519
|
+
if (!leftDate || !rightDate) return 0;
|
|
1520
|
+
return Math.round((rightDate.getTime() - leftDate.getTime()) / 864e5);
|
|
1521
|
+
}
|
|
1522
|
+
function timePart(value, fallback = "00:00:00") {
|
|
1523
|
+
const match = value?.match(/[T ](\d{2}):(\d{2})(?::(\d{2}))?/);
|
|
1524
|
+
return match ? `${match[1]}:${match[2]}:${match[3] ?? "00"}` : fallback;
|
|
1525
|
+
}
|
|
1526
|
+
function withTime(date, time, showSecond = false) {
|
|
1527
|
+
if (!date) return "";
|
|
1528
|
+
const [hour = "00", minute = "00", second = "00"] = time.split(":");
|
|
1529
|
+
return `${date} ${hour}:${minute}${showSecond ? `:${second}` : ""}`;
|
|
1530
|
+
}
|
|
1531
|
+
function normalizeDateValue(value, showTime, index = 0) {
|
|
1532
|
+
if (!value) return "";
|
|
1533
|
+
const date = parseDate(value);
|
|
1534
|
+
if (!date) return value;
|
|
1535
|
+
const day = dateKey(date);
|
|
1536
|
+
if (!showTime) return day;
|
|
1537
|
+
const config = typeof showTime === "object" ? showTime : {};
|
|
1538
|
+
const fallback = typeof config.defaultValue === "string" ? config.defaultValue : config.defaultValue?.[index] ?? "00:00:00";
|
|
1539
|
+
return withTime(day, timePart(value, fallback), Boolean(config.showSecond));
|
|
1540
|
+
}
|
|
1541
|
+
var WEEKDAYS = ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"];
|
|
1542
|
+
function CalendarMonth({
|
|
1543
|
+
month,
|
|
1544
|
+
selectedDates = [],
|
|
1545
|
+
range = ["", ""],
|
|
1546
|
+
previewEnd,
|
|
1547
|
+
disabledDate,
|
|
1548
|
+
onSelect,
|
|
1549
|
+
onHover
|
|
1550
|
+
}) {
|
|
1551
|
+
const first = startOfMonth(month);
|
|
1552
|
+
const mondayIndex = (first.getDay() + 6) % 7;
|
|
1553
|
+
const gridStart = addDays(first, -mondayIndex);
|
|
1554
|
+
const today = dateKey(/* @__PURE__ */ new Date());
|
|
1555
|
+
const start = range[0];
|
|
1556
|
+
const end = range[1] || previewEnd || "";
|
|
1557
|
+
const low = start && end ? start <= end ? start : end : "";
|
|
1558
|
+
const high = start && end ? start <= end ? end : start : "";
|
|
1559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sia-date-panel__month", children: [
|
|
1560
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "sia-date-panel__weekdays", "aria-hidden": "true", children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: day }, day)) }),
|
|
1561
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "sia-date-panel__days", children: Array.from({ length: 42 }, (_, index) => {
|
|
1562
|
+
const date = addDays(gridStart, index);
|
|
1563
|
+
const key = dateKey(date);
|
|
1564
|
+
const outside = date.getMonth() !== month.getMonth();
|
|
1565
|
+
const disabled = disabledDate?.(key) ?? false;
|
|
1566
|
+
const selected = selectedDates.includes(key);
|
|
1567
|
+
const rangeStart = Boolean(start && key === start);
|
|
1568
|
+
const rangeEnd = Boolean(range[1] && key === range[1]);
|
|
1569
|
+
const inRange = Boolean(low && high && key >= low && key <= high);
|
|
1570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1571
|
+
"span",
|
|
1572
|
+
{
|
|
1573
|
+
className: `sia-date-panel__cell${outside ? " is-outside" : ""}${selected ? " is-selected" : ""}${rangeStart ? " is-range-start" : ""}${rangeEnd ? " is-range-end" : ""}${inRange ? " is-in-range" : ""}${key === today ? " is-today" : ""}`,
|
|
1574
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1575
|
+
"button",
|
|
1576
|
+
{
|
|
1577
|
+
type: "button",
|
|
1578
|
+
"aria-label": key,
|
|
1579
|
+
"aria-pressed": selected || rangeStart || rangeEnd || void 0,
|
|
1580
|
+
disabled,
|
|
1581
|
+
onClick: () => onSelect(key),
|
|
1582
|
+
onMouseEnter: () => onHover?.(key),
|
|
1583
|
+
children: date.getDate()
|
|
1584
|
+
}
|
|
1585
|
+
)
|
|
1586
|
+
},
|
|
1587
|
+
key
|
|
1588
|
+
);
|
|
1589
|
+
}) })
|
|
1590
|
+
] });
|
|
1591
|
+
}
|
|
1592
|
+
function CalendarHeader({
|
|
1593
|
+
month,
|
|
1594
|
+
label,
|
|
1595
|
+
range = false,
|
|
1596
|
+
onPreviousYear,
|
|
1597
|
+
onPreviousMonth,
|
|
1598
|
+
onNextMonth,
|
|
1599
|
+
onNextYear
|
|
1600
|
+
}) {
|
|
1601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sia-date-panel__header", children: [
|
|
1602
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "sia-date-panel__nav", children: [
|
|
1603
|
+
onPreviousYear ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "aria-label": "\u4E0A\u4E00\u5E74", onClick: onPreviousYear, children: [
|
|
1604
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-left", size: 13 }),
|
|
1605
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-left", size: 13 })
|
|
1606
|
+
] }) : null,
|
|
1607
|
+
onPreviousMonth ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": "\u4E0A\u4E2A\u6708", onClick: onPreviousMonth, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-left", size: 15 }) }) : null
|
|
1608
|
+
] }),
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
|
|
1610
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: label }) : null,
|
|
1611
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
1612
|
+
month.getFullYear(),
|
|
1613
|
+
"\u5E74\xA0 ",
|
|
1614
|
+
month.getMonth() + 1,
|
|
1615
|
+
"\u6708"
|
|
1616
|
+
] })
|
|
1617
|
+
] }),
|
|
1618
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "sia-date-panel__nav", children: [
|
|
1619
|
+
onNextMonth ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": "\u4E0B\u4E2A\u6708", onClick: onNextMonth, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-right", size: 15 }) }) : null,
|
|
1620
|
+
onNextYear ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "aria-label": "\u4E0B\u4E00\u5E74", onClick: onNextYear, children: [
|
|
1621
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-right", size: 13 }),
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "chevron-right", size: 13 })
|
|
1623
|
+
] }) : null
|
|
1624
|
+
] }),
|
|
1625
|
+
range ? null : null
|
|
1626
|
+
] });
|
|
1627
|
+
}
|
|
1628
|
+
function TimePanel({
|
|
1629
|
+
value,
|
|
1630
|
+
showSecond = false,
|
|
1631
|
+
ariaLabel = "\u65F6\u95F4",
|
|
1632
|
+
disabledTime,
|
|
1633
|
+
use12Hours = false,
|
|
1634
|
+
onChange
|
|
1635
|
+
}) {
|
|
1636
|
+
const [hour = "00", minute = "00", second = "00"] = value.split(":");
|
|
1637
|
+
const columnsRef = (0, import_react6.useRef)(null);
|
|
1638
|
+
const hourRef = (0, import_react6.useRef)(null);
|
|
1639
|
+
const minuteRef = (0, import_react6.useRef)(null);
|
|
1640
|
+
const secondRef = (0, import_react6.useRef)(null);
|
|
1641
|
+
const columnRefs = [hourRef, minuteRef, secondRef];
|
|
1642
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
1643
|
+
for (const column of columnsRef.current?.children ?? []) {
|
|
1644
|
+
const selected = column.querySelector('[aria-selected="true"]');
|
|
1645
|
+
const first = column.firstElementChild;
|
|
1646
|
+
if (!selected || !first) continue;
|
|
1647
|
+
const top = selected.offsetTop - first.offsetTop + parseFloat(getComputedStyle(column).paddingTop || "0");
|
|
1648
|
+
const bottom = top + selected.offsetHeight;
|
|
1649
|
+
if (top < column.scrollTop || bottom > column.scrollTop + column.clientHeight) {
|
|
1650
|
+
column.scrollTop = Math.max(0, top - (column.clientHeight - selected.offsetHeight) / 2);
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}, [hour, minute, second, showSecond, ariaLabel]);
|
|
1654
|
+
const columns = [
|
|
1655
|
+
{ label: "\u5C0F\u65F6", value: hour, count: 24, index: 0 },
|
|
1656
|
+
{ label: "\u5206\u949F", value: minute, count: 60, index: 1 },
|
|
1657
|
+
...showSecond ? [{ label: "\u79D2", value: second, count: 60, index: 2 }] : []
|
|
1277
1658
|
];
|
|
1278
1659
|
function update(index, next) {
|
|
1279
1660
|
const values = [hour, minute, second];
|
|
@@ -1288,7 +1669,7 @@ function TimePanel({
|
|
|
1288
1669
|
showSecond ? `:${second}` : "",
|
|
1289
1670
|
use12Hours ? Number(hour) < 12 ? " AM" : " PM" : ""
|
|
1290
1671
|
] }),
|
|
1291
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: columnsRef, className: "sia-date-panel__time-columns", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { role: "listbox", "aria-label": `${ariaLabel}${column.label}`, children: Array.from({ length: column.count }, (_, index) => {
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: columnsRef, className: "sia-date-panel__time-columns", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: columnRefs[column.index], role: "listbox", "aria-label": `${ariaLabel}${column.label}`, children: Array.from({ length: column.count }, (_, index) => {
|
|
1292
1673
|
const next = pad(index);
|
|
1293
1674
|
const candidate = [hour, minute, second];
|
|
1294
1675
|
candidate[column.index] = next;
|
|
@@ -1300,7 +1681,8 @@ function TimePanel({
|
|
|
1300
1681
|
const target = event.key === "Home" ? 0 : event.key === "End" ? buttons.length - 1 : Math.max(0, Math.min(buttons.length - 1, position + (event.key === "ArrowDown" ? 1 : -1)));
|
|
1301
1682
|
buttons[target]?.focus();
|
|
1302
1683
|
}, onClick: () => update(column.index, next), children: use12Hours && column.index === 0 ? `${pad(index % 12 || 12)} ${index < 12 ? "AM" : "PM"}` : next }, next);
|
|
1303
|
-
}) }, column.label)) })
|
|
1684
|
+
}) }, column.label)) }),
|
|
1685
|
+
columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloatingScrollbarProvider, { targetRef: columnRefs[column.index] }, column.index))
|
|
1304
1686
|
] });
|
|
1305
1687
|
}
|
|
1306
1688
|
function DatePanelFooter({
|
|
@@ -1398,23 +1780,23 @@ function DatePicker({
|
|
|
1398
1780
|
...props
|
|
1399
1781
|
}) {
|
|
1400
1782
|
const size = useControlSize(sizeProp);
|
|
1401
|
-
const id = (0,
|
|
1402
|
-
const rootRef = (0,
|
|
1403
|
-
const popupRef = (0,
|
|
1783
|
+
const id = (0, import_react7.useId)();
|
|
1784
|
+
const rootRef = (0, import_react7.useRef)(null);
|
|
1785
|
+
const popupRef = (0, import_react7.useRef)(null);
|
|
1404
1786
|
const initialValue = defaultValue ?? (multiple ? [] : "");
|
|
1405
1787
|
const [currentValue, setCurrentValue] = useControllableState({ value, defaultValue: initialValue, onChange });
|
|
1406
1788
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
1407
|
-
const [draftValue, setDraftValue] = (0,
|
|
1789
|
+
const [draftValue, setDraftValue] = (0, import_react7.useState)(currentValue);
|
|
1408
1790
|
const firstCurrent = Array.isArray(currentValue) ? currentValue[0] : currentValue;
|
|
1409
|
-
const [viewMonth, setViewMonth] = (0,
|
|
1410
|
-
const [draftTime, setDraftTime] = (0,
|
|
1791
|
+
const [viewMonth, setViewMonth] = (0, import_react7.useState)(() => startOfMonth(parseDate(dayFromValue(firstCurrent)) ?? /* @__PURE__ */ new Date()));
|
|
1792
|
+
const [draftTime, setDraftTime] = (0, import_react7.useState)(() => timePart(firstCurrent, defaultTimeFrom(showTime)));
|
|
1411
1793
|
const resolvedNeedConfirm = needConfirm ?? Boolean(showTime);
|
|
1412
1794
|
const showSecond = showSecondFrom(showTime);
|
|
1413
|
-
const selectedDates = (0,
|
|
1795
|
+
const selectedDates = (0, import_react7.useMemo)(() => {
|
|
1414
1796
|
const values = Array.isArray(draftValue) ? draftValue : draftValue ? [draftValue] : [];
|
|
1415
1797
|
return values.map(dayFromValue).filter(Boolean);
|
|
1416
1798
|
}, [draftValue]);
|
|
1417
|
-
(0,
|
|
1799
|
+
(0, import_react7.useEffect)(() => {
|
|
1418
1800
|
if (!visible) return void 0;
|
|
1419
1801
|
const close = (event) => {
|
|
1420
1802
|
const target = event.target;
|
|
@@ -1580,28 +1962,28 @@ function DateRangePicker({
|
|
|
1580
1962
|
...props
|
|
1581
1963
|
}) {
|
|
1582
1964
|
const size = useControlSize(sizeProp);
|
|
1583
|
-
const id = (0,
|
|
1584
|
-
const rootRef = (0,
|
|
1585
|
-
const popupRef = (0,
|
|
1965
|
+
const id = (0, import_react7.useId)();
|
|
1966
|
+
const rootRef = (0, import_react7.useRef)(null);
|
|
1967
|
+
const popupRef = (0, import_react7.useRef)(null);
|
|
1586
1968
|
const [currentValue, setCurrentValue] = useControllableState({ value: value === void 0 ? void 0 : Array.isArray(value) ? value : ["", ""], defaultValue, onChange });
|
|
1587
1969
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
1588
|
-
const [draftValue, setDraftValue] = (0,
|
|
1589
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
1590
|
-
const [hoverDate, setHoverDate] = (0,
|
|
1591
|
-
const [viewMonth, setViewMonth] = (0,
|
|
1592
|
-
const [endViewMonth, setEndViewMonth] = (0,
|
|
1593
|
-
const [compactDateTime, setCompactDateTime] = (0,
|
|
1970
|
+
const [draftValue, setDraftValue] = (0, import_react7.useState)(currentValue);
|
|
1971
|
+
const [activeIndex, setActiveIndex] = (0, import_react7.useState)(currentValue[0] && !currentValue[1] ? 1 : 0);
|
|
1972
|
+
const [hoverDate, setHoverDate] = (0, import_react7.useState)("");
|
|
1973
|
+
const [viewMonth, setViewMonth] = (0, import_react7.useState)(() => startOfMonth(parseDate(dayFromValue(currentValue[0] || currentValue[1])) ?? /* @__PURE__ */ new Date()));
|
|
1974
|
+
const [endViewMonth, setEndViewMonth] = (0, import_react7.useState)(() => startOfMonth(parseDate(dayFromValue(currentValue[1])) ?? addMonths(parseDate(dayFromValue(currentValue[0])) ?? /* @__PURE__ */ new Date(), 1)));
|
|
1975
|
+
const [compactDateTime, setCompactDateTime] = (0, import_react7.useState)(false);
|
|
1594
1976
|
const showSecond = showSecondFrom(showTime);
|
|
1595
1977
|
const defaultTime = defaultTimeFrom(showTime);
|
|
1596
1978
|
const defaultEndTime = defaultTimeFrom(showTime, 1);
|
|
1597
|
-
const [times, setTimes] = (0,
|
|
1979
|
+
const [times, setTimes] = (0, import_react7.useState)([
|
|
1598
1980
|
timePart(currentValue[0], defaultTime),
|
|
1599
1981
|
timePart(currentValue[1], defaultEndTime)
|
|
1600
1982
|
]);
|
|
1601
1983
|
const resolvedNeedConfirm = needConfirm ?? Boolean(showTime);
|
|
1602
1984
|
const rangeDates = [dayFromValue(draftValue[0]), dayFromValue(draftValue[1])];
|
|
1603
1985
|
const invalidDateTimeRange = Boolean(showTime && draftValue[0] && draftValue[1] && draftValue[0] > draftValue[1]);
|
|
1604
|
-
(0,
|
|
1986
|
+
(0, import_react7.useEffect)(() => {
|
|
1605
1987
|
if (!showTime || typeof document === "undefined") {
|
|
1606
1988
|
setCompactDateTime(false);
|
|
1607
1989
|
return void 0;
|
|
@@ -1614,7 +1996,7 @@ function DateRangePicker({
|
|
|
1614
1996
|
window.addEventListener("resize", updateLayout);
|
|
1615
1997
|
return () => window.removeEventListener("resize", updateLayout);
|
|
1616
1998
|
}, [showSecond, showTime]);
|
|
1617
|
-
(0,
|
|
1999
|
+
(0, import_react7.useEffect)(() => {
|
|
1618
2000
|
if (!visible) return void 0;
|
|
1619
2001
|
const close = (event) => {
|
|
1620
2002
|
const target = event.target;
|
|
@@ -1918,13 +2300,13 @@ function DateRangePicker({
|
|
|
1918
2300
|
var import_react16 = require("react");
|
|
1919
2301
|
|
|
1920
2302
|
// src/components/Modal.tsx
|
|
1921
|
-
var
|
|
2303
|
+
var import_react10 = require("react");
|
|
1922
2304
|
var import_client2 = require("react-dom/client");
|
|
1923
2305
|
|
|
1924
2306
|
// src/components/Button.tsx
|
|
1925
|
-
var
|
|
2307
|
+
var import_react8 = require("react");
|
|
1926
2308
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1927
|
-
var Button = (0,
|
|
2309
|
+
var Button = (0, import_react8.forwardRef)(function Button2({
|
|
1928
2310
|
variant = "default",
|
|
1929
2311
|
size: sizeProp,
|
|
1930
2312
|
loading = false,
|
|
@@ -1940,7 +2322,7 @@ var Button = (0, import_react6.forwardRef)(function Button2({
|
|
|
1940
2322
|
...props
|
|
1941
2323
|
}, forwardedRef) {
|
|
1942
2324
|
const size = useControlSize(sizeProp);
|
|
1943
|
-
const localRef = (0,
|
|
2325
|
+
const localRef = (0, import_react8.useRef)(null);
|
|
1944
2326
|
function setRef(node) {
|
|
1945
2327
|
localRef.current = node;
|
|
1946
2328
|
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
@@ -1979,7 +2361,7 @@ var Button = (0, import_react6.forwardRef)(function Button2({
|
|
|
1979
2361
|
});
|
|
1980
2362
|
|
|
1981
2363
|
// src/components/Overlay.tsx
|
|
1982
|
-
var
|
|
2364
|
+
var import_react9 = require("react");
|
|
1983
2365
|
var import_react_dom2 = require("react-dom");
|
|
1984
2366
|
var bodyLockCount = 0;
|
|
1985
2367
|
var previousBodyOverflow = "";
|
|
@@ -2001,10 +2383,10 @@ function focusableElements(container) {
|
|
|
2001
2383
|
)].filter((element) => !element.hidden && element.getAttribute("aria-hidden") !== "true");
|
|
2002
2384
|
}
|
|
2003
2385
|
function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
|
|
2004
|
-
const overlayIdRef = (0,
|
|
2005
|
-
const closeRef = (0,
|
|
2386
|
+
const overlayIdRef = (0, import_react9.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
|
|
2387
|
+
const closeRef = (0, import_react9.useRef)(onRequestClose);
|
|
2006
2388
|
closeRef.current = onRequestClose;
|
|
2007
|
-
(0,
|
|
2389
|
+
(0, import_react9.useEffect)(() => {
|
|
2008
2390
|
if (!open || typeof document === "undefined") return void 0;
|
|
2009
2391
|
const overlayId = overlayIdRef.current;
|
|
2010
2392
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -2068,7 +2450,7 @@ var typeIcons = {
|
|
|
2068
2450
|
error: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: "circle-close", size: 23 }),
|
|
2069
2451
|
confirm: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: "question", size: 23 })
|
|
2070
2452
|
};
|
|
2071
|
-
var ModalRoot = (0,
|
|
2453
|
+
var ModalRoot = (0, import_react10.forwardRef)(function Modal({
|
|
2072
2454
|
open,
|
|
2073
2455
|
title,
|
|
2074
2456
|
children,
|
|
@@ -2097,20 +2479,20 @@ var ModalRoot = (0, import_react8.forwardRef)(function Modal({
|
|
|
2097
2479
|
style,
|
|
2098
2480
|
...props
|
|
2099
2481
|
}, forwardedRef) {
|
|
2100
|
-
const localRef = (0,
|
|
2101
|
-
const titleId = (0,
|
|
2102
|
-
const [submitting, setSubmitting] = (0,
|
|
2103
|
-
const [rendered, setRendered] = (0,
|
|
2104
|
-
const [closing, setClosing] = (0,
|
|
2105
|
-
const afterOpenChangeRef = (0,
|
|
2482
|
+
const localRef = (0, import_react10.useRef)(null);
|
|
2483
|
+
const titleId = (0, import_react10.useId)();
|
|
2484
|
+
const [submitting, setSubmitting] = (0, import_react10.useState)(false);
|
|
2485
|
+
const [rendered, setRendered] = (0, import_react10.useState)(open);
|
|
2486
|
+
const [closing, setClosing] = (0, import_react10.useState)(false);
|
|
2487
|
+
const afterOpenChangeRef = (0, import_react10.useRef)(afterOpenChange);
|
|
2106
2488
|
afterOpenChangeRef.current = afterOpenChange;
|
|
2107
|
-
const submitLock = (0,
|
|
2108
|
-
(0,
|
|
2489
|
+
const submitLock = (0, import_react10.useRef)(false);
|
|
2490
|
+
(0, import_react10.useEffect)(() => {
|
|
2109
2491
|
if (!open || !rendered) return void 0;
|
|
2110
2492
|
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
2111
2493
|
return () => window.clearTimeout(timer);
|
|
2112
2494
|
}, [open, rendered]);
|
|
2113
|
-
(0,
|
|
2495
|
+
(0, import_react10.useEffect)(() => {
|
|
2114
2496
|
if (open) {
|
|
2115
2497
|
setRendered(true);
|
|
2116
2498
|
setClosing(false);
|
|
@@ -2285,16 +2667,16 @@ var Modal2 = Object.assign(ModalRoot, {
|
|
|
2285
2667
|
});
|
|
2286
2668
|
|
|
2287
2669
|
// src/components/Input.tsx
|
|
2288
|
-
var
|
|
2670
|
+
var import_react11 = require("react");
|
|
2289
2671
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2290
|
-
var Input = (0,
|
|
2672
|
+
var Input = (0, import_react11.forwardRef)(function Input2({
|
|
2291
2673
|
label,
|
|
2292
2674
|
hint,
|
|
2293
2675
|
status = "default",
|
|
2294
2676
|
size: sizeProp,
|
|
2295
2677
|
prefix,
|
|
2296
2678
|
suffix,
|
|
2297
|
-
allowClear =
|
|
2679
|
+
allowClear = true,
|
|
2298
2680
|
onClear,
|
|
2299
2681
|
showCount = false,
|
|
2300
2682
|
placeholderMode,
|
|
@@ -2309,10 +2691,10 @@ var Input = (0, import_react9.forwardRef)(function Input2({
|
|
|
2309
2691
|
...props
|
|
2310
2692
|
}, forwardedRef) {
|
|
2311
2693
|
const size = useControlSize(sizeProp);
|
|
2312
|
-
const fallbackId = (0,
|
|
2694
|
+
const fallbackId = (0, import_react11.useId)();
|
|
2313
2695
|
const inputId = id ?? fallbackId;
|
|
2314
|
-
const localRef = (0,
|
|
2315
|
-
const [uncontrolledValue, setUncontrolledValue] = (0,
|
|
2696
|
+
const localRef = (0, import_react11.useRef)(null);
|
|
2697
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react11.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
|
|
2316
2698
|
const currentText = value !== void 0 ? String(value) : uncontrolledValue;
|
|
2317
2699
|
const hasValue = currentText.length > 0;
|
|
2318
2700
|
const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
|
|
@@ -2389,17 +2771,17 @@ var Input = (0, import_react9.forwardRef)(function Input2({
|
|
|
2389
2771
|
});
|
|
2390
2772
|
|
|
2391
2773
|
// src/components/Checkbox.tsx
|
|
2392
|
-
var
|
|
2774
|
+
var import_react12 = require("react");
|
|
2393
2775
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2394
|
-
var CheckboxGroupContext = (0,
|
|
2395
|
-
var CheckboxRoot = (0,
|
|
2776
|
+
var CheckboxGroupContext = (0, import_react12.createContext)(null);
|
|
2777
|
+
var CheckboxRoot = (0, import_react12.forwardRef)(function Checkbox({ value, size: sizeProp, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
|
|
2396
2778
|
const size = useControlSize(sizeProp);
|
|
2397
|
-
const group = (0,
|
|
2398
|
-
const localRef = (0,
|
|
2399
|
-
const fallbackId = (0,
|
|
2779
|
+
const group = (0, import_react12.useContext)(CheckboxGroupContext);
|
|
2780
|
+
const localRef = (0, import_react12.useRef)(null);
|
|
2781
|
+
const fallbackId = (0, import_react12.useId)();
|
|
2400
2782
|
const grouped = group !== null && value !== void 0;
|
|
2401
2783
|
const currentChecked = grouped ? group.values.includes(value) : checked;
|
|
2402
|
-
(0,
|
|
2784
|
+
(0, import_react12.useEffect)(() => {
|
|
2403
2785
|
if (localRef.current) localRef.current.indeterminate = indeterminate;
|
|
2404
2786
|
}, [indeterminate]);
|
|
2405
2787
|
function setRef(node) {
|
|
@@ -2444,7 +2826,7 @@ function CheckboxGroup({
|
|
|
2444
2826
|
}) {
|
|
2445
2827
|
const size = useControlSize(sizeProp);
|
|
2446
2828
|
const [values, setValues] = useControllableState({ value, defaultValue, onChange });
|
|
2447
|
-
const context = (0,
|
|
2829
|
+
const context = (0, import_react12.useMemo)(() => ({
|
|
2448
2830
|
values,
|
|
2449
2831
|
disabled,
|
|
2450
2832
|
name,
|
|
@@ -2467,10 +2849,10 @@ var Checkbox2 = Object.assign(CheckboxRoot, {
|
|
|
2467
2849
|
});
|
|
2468
2850
|
|
|
2469
2851
|
// src/components/SelectionPanel.tsx
|
|
2470
|
-
var
|
|
2852
|
+
var import_react14 = require("react");
|
|
2471
2853
|
|
|
2472
2854
|
// src/components/FloatingDisplay.tsx
|
|
2473
|
-
var
|
|
2855
|
+
var import_react13 = require("react");
|
|
2474
2856
|
var import_react_dom3 = require("react-dom");
|
|
2475
2857
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2476
2858
|
var FLOATING_GAP = 9;
|
|
@@ -2528,17 +2910,17 @@ function Floating({
|
|
|
2528
2910
|
role = "tooltip",
|
|
2529
2911
|
onOpenChange
|
|
2530
2912
|
}) {
|
|
2531
|
-
const rootRef = (0,
|
|
2532
|
-
const overlayRef = (0,
|
|
2533
|
-
const enterTimer = (0,
|
|
2534
|
-
const leaveTimer = (0,
|
|
2535
|
-
const contentId = (0,
|
|
2913
|
+
const rootRef = (0, import_react13.useRef)(null);
|
|
2914
|
+
const overlayRef = (0, import_react13.useRef)(null);
|
|
2915
|
+
const enterTimer = (0, import_react13.useRef)();
|
|
2916
|
+
const leaveTimer = (0, import_react13.useRef)();
|
|
2917
|
+
const contentId = (0, import_react13.useId)();
|
|
2536
2918
|
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
2537
2919
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
2538
|
-
const [position, setPosition] = (0,
|
|
2539
|
-
const setVisibleRef = (0,
|
|
2920
|
+
const [position, setPosition] = (0, import_react13.useState)();
|
|
2921
|
+
const setVisibleRef = (0, import_react13.useRef)(setVisible);
|
|
2540
2922
|
setVisibleRef.current = setVisible;
|
|
2541
|
-
const closeSelfRef = (0,
|
|
2923
|
+
const closeSelfRef = (0, import_react13.useRef)();
|
|
2542
2924
|
if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
|
|
2543
2925
|
const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
|
|
2544
2926
|
function openNow() {
|
|
@@ -2566,7 +2948,7 @@ function Floating({
|
|
|
2566
2948
|
if (delay <= 0) closeNow();
|
|
2567
2949
|
else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
|
|
2568
2950
|
}
|
|
2569
|
-
(0,
|
|
2951
|
+
(0, import_react13.useEffect)(() => {
|
|
2570
2952
|
if (!visible || !triggers.includes("click")) return;
|
|
2571
2953
|
const close = (event) => {
|
|
2572
2954
|
const target = event.target;
|
|
@@ -2575,7 +2957,7 @@ function Floating({
|
|
|
2575
2957
|
document.addEventListener("pointerdown", close);
|
|
2576
2958
|
return () => document.removeEventListener("pointerdown", close);
|
|
2577
2959
|
}, [triggers.join("|"), visible]);
|
|
2578
|
-
(0,
|
|
2960
|
+
(0, import_react13.useLayoutEffect)(() => {
|
|
2579
2961
|
if (!visible) {
|
|
2580
2962
|
setPosition(void 0);
|
|
2581
2963
|
return;
|
|
@@ -2596,11 +2978,11 @@ function Floating({
|
|
|
2596
2978
|
observer.disconnect();
|
|
2597
2979
|
};
|
|
2598
2980
|
}, [children, content, placement, visible]);
|
|
2599
|
-
(0,
|
|
2981
|
+
(0, import_react13.useEffect)(() => () => {
|
|
2600
2982
|
clearTimers();
|
|
2601
2983
|
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
2602
2984
|
}, []);
|
|
2603
|
-
const child = (0,
|
|
2985
|
+
const child = (0, import_react13.cloneElement)(children, {
|
|
2604
2986
|
...triggers.includes("hover") ? { onMouseEnter: (event) => {
|
|
2605
2987
|
children.props.onMouseEnter?.(event);
|
|
2606
2988
|
show(mouseEnterDelay);
|
|
@@ -2680,26 +3062,26 @@ function SelectionPanel({
|
|
|
2680
3062
|
maxHeight = 250,
|
|
2681
3063
|
autoFocusSearch = false
|
|
2682
3064
|
}) {
|
|
2683
|
-
const [localSearch, setLocalSearch] = (0,
|
|
3065
|
+
const [localSearch, setLocalSearch] = (0, import_react14.useState)("");
|
|
2684
3066
|
const search = searchValue ?? localSearch;
|
|
2685
|
-
const [scrollTop, setScrollTop] = (0,
|
|
2686
|
-
const [active, setActive] = (0,
|
|
2687
|
-
const [keyboardActive, setKeyboardActive] = (0,
|
|
2688
|
-
const [deselectedHover, setDeselectedHover] = (0,
|
|
2689
|
-
const listRef = (0,
|
|
2690
|
-
const id = (0,
|
|
2691
|
-
const selected = (0,
|
|
3067
|
+
const [scrollTop, setScrollTop] = (0, import_react14.useState)(0);
|
|
3068
|
+
const [active, setActive] = (0, import_react14.useState)();
|
|
3069
|
+
const [keyboardActive, setKeyboardActive] = (0, import_react14.useState)(false);
|
|
3070
|
+
const [deselectedHover, setDeselectedHover] = (0, import_react14.useState)();
|
|
3071
|
+
const listRef = (0, import_react14.useRef)(null);
|
|
3072
|
+
const id = (0, import_react14.useId)();
|
|
3073
|
+
const selected = (0, import_react14.useMemo)(() => new Set(value), [value]);
|
|
2692
3074
|
const count = Math.max(1, Math.floor(columns));
|
|
2693
|
-
const allOptions = (0,
|
|
3075
|
+
const allOptions = (0, import_react14.useMemo)(() => {
|
|
2694
3076
|
if (!includeUnknownValues) return [...options];
|
|
2695
3077
|
const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
|
|
2696
3078
|
return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
|
|
2697
3079
|
}, [options, value, includeUnknownValues]);
|
|
2698
|
-
const filtered = (0,
|
|
3080
|
+
const filtered = (0, import_react14.useMemo)(
|
|
2699
3081
|
() => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
|
|
2700
3082
|
[allOptions, selectedOnly, selected, search]
|
|
2701
3083
|
);
|
|
2702
|
-
const rows = (0,
|
|
3084
|
+
const rows = (0, import_react14.useMemo)(() => {
|
|
2703
3085
|
const groups = /* @__PURE__ */ new Map();
|
|
2704
3086
|
filtered.forEach((option) => {
|
|
2705
3087
|
const items = groups.get(option.group) ?? [];
|
|
@@ -2725,7 +3107,7 @@ function SelectionPanel({
|
|
|
2725
3107
|
const virtual = filtered.length > 100;
|
|
2726
3108
|
const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
|
|
2727
3109
|
const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
|
|
2728
|
-
(0,
|
|
3110
|
+
(0, import_react14.useEffect)(() => {
|
|
2729
3111
|
setScrollTop(0);
|
|
2730
3112
|
if (listRef.current) listRef.current.scrollTop = 0;
|
|
2731
3113
|
setActive(void 0);
|
|
@@ -2749,6 +3131,7 @@ function SelectionPanel({
|
|
|
2749
3131
|
onChange([...retained, ...add]);
|
|
2750
3132
|
}
|
|
2751
3133
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sia-selection-panel", children: [
|
|
3134
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FloatingScrollbarProvider, { targetRef: listRef }),
|
|
2752
3135
|
showSearch && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2753
3136
|
Input,
|
|
2754
3137
|
{
|
|
@@ -2829,445 +3212,70 @@ function SelectionPanel({
|
|
|
2829
3212
|
if (deselectedHover === option.value) setDeselectedHover(void 0);
|
|
2830
3213
|
},
|
|
2831
3214
|
onClick: (event) => {
|
|
2832
|
-
if (!event.target.closest(".sia-checkbox")) toggle(option);
|
|
2833
|
-
},
|
|
2834
|
-
children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "sia-selection-panel__text", children: [
|
|
2835
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
2836
|
-
showValue && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { children: String(option.value) })
|
|
2837
|
-
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "sia-selection-panel__text", children: [
|
|
2838
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
2839
|
-
showValue && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { children: String(option.value) })
|
|
2840
|
-
] })
|
|
2841
|
-
}
|
|
2842
|
-
) }, `${typeof option.value}-${option.value}`))
|
|
2843
|
-
},
|
|
2844
|
-
row.key
|
|
2845
|
-
)) })
|
|
2846
|
-
}
|
|
2847
|
-
)
|
|
2848
|
-
] });
|
|
2849
|
-
}
|
|
2850
|
-
|
|
2851
|
-
// src/components/OverflowTags.tsx
|
|
2852
|
-
var import_react13 = require("react");
|
|
2853
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2854
|
-
function OverflowTags({ items, maxCount, className = "", tagClassName, restClassName = "" }) {
|
|
2855
|
-
const rootRef = (0, import_react13.useRef)(null);
|
|
2856
|
-
const measureRef = (0, import_react13.useRef)(null);
|
|
2857
|
-
const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount) || 0));
|
|
2858
|
-
const [visibleCount, setVisibleCount] = (0, import_react13.useState)(0);
|
|
2859
|
-
(0, import_react13.useLayoutEffect)(() => {
|
|
2860
|
-
const root = rootRef.current;
|
|
2861
|
-
const measure = measureRef.current;
|
|
2862
|
-
if (!root || !measure) return;
|
|
2863
|
-
const update = () => {
|
|
2864
|
-
const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
|
|
2865
|
-
const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
|
|
2866
|
-
let used = 0;
|
|
2867
|
-
let fitting = 0;
|
|
2868
|
-
for (let count2 = 1; count2 <= limit; count2 += 1) {
|
|
2869
|
-
used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
|
|
2870
|
-
const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
|
|
2871
|
-
if (used + rest <= root.clientWidth) fitting = count2;
|
|
2872
|
-
}
|
|
2873
|
-
setVisibleCount((previous) => previous === fitting ? previous : fitting);
|
|
2874
|
-
};
|
|
2875
|
-
update();
|
|
2876
|
-
const observer = new ResizeObserver(update);
|
|
2877
|
-
observer.observe(root);
|
|
2878
|
-
for (const child of measure.children) observer.observe(child);
|
|
2879
|
-
return () => observer.disconnect();
|
|
2880
|
-
}, [items, limit]);
|
|
2881
|
-
const count = Math.min(visibleCount, limit);
|
|
2882
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
|
|
2883
|
-
items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
2884
|
-
items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
|
|
2885
|
-
"+",
|
|
2886
|
-
items.length - count
|
|
2887
|
-
] }) : null,
|
|
2888
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
|
|
2889
|
-
items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
2890
|
-
Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
|
|
2891
|
-
"+",
|
|
2892
|
-
items.length - index
|
|
2893
|
-
] }, `rest-${index}`))
|
|
2894
|
-
] })
|
|
2895
|
-
] });
|
|
2896
|
-
}
|
|
2897
|
-
|
|
2898
|
-
// src/components/FloatingScrollbarProvider.tsx
|
|
2899
|
-
var import_react15 = require("react");
|
|
2900
|
-
|
|
2901
|
-
// src/components/useScrollbarProximity.ts
|
|
2902
|
-
var import_react14 = require("react");
|
|
2903
|
-
var users = 0;
|
|
2904
|
-
var cleanup;
|
|
2905
|
-
function useScrollbarProximity() {
|
|
2906
|
-
(0, import_react14.useEffect)(() => {
|
|
2907
|
-
if (users++ === 0) {
|
|
2908
|
-
let frame = 0;
|
|
2909
|
-
let x = -Infinity;
|
|
2910
|
-
let y = -Infinity;
|
|
2911
|
-
const nearby = /* @__PURE__ */ new Set();
|
|
2912
|
-
const clear = () => {
|
|
2913
|
-
nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
|
|
2914
|
-
nearby.clear();
|
|
2915
|
-
};
|
|
2916
|
-
const update = () => {
|
|
2917
|
-
frame = 0;
|
|
2918
|
-
const next = /* @__PURE__ */ new Set();
|
|
2919
|
-
document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
|
|
2920
|
-
const rect = track.getBoundingClientRect();
|
|
2921
|
-
const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
|
|
2922
|
-
if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
|
|
2923
|
-
next.add(track);
|
|
2924
|
-
if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
|
|
2925
|
-
}
|
|
2926
|
-
});
|
|
2927
|
-
nearby.forEach((track) => {
|
|
2928
|
-
if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
|
|
2929
|
-
});
|
|
2930
|
-
nearby.clear();
|
|
2931
|
-
next.forEach((track) => nearby.add(track));
|
|
2932
|
-
};
|
|
2933
|
-
const move = (event) => {
|
|
2934
|
-
if (event.pointerType === "touch") return;
|
|
2935
|
-
x = event.clientX;
|
|
2936
|
-
y = event.clientY;
|
|
2937
|
-
if (!frame) frame = requestAnimationFrame(update);
|
|
2938
|
-
};
|
|
2939
|
-
const leave = () => {
|
|
2940
|
-
x = y = -Infinity;
|
|
2941
|
-
clear();
|
|
2942
|
-
};
|
|
2943
|
-
document.addEventListener("pointermove", move, { passive: true });
|
|
2944
|
-
document.documentElement.addEventListener("pointerleave", leave);
|
|
2945
|
-
window.addEventListener("blur", leave);
|
|
2946
|
-
cleanup = () => {
|
|
2947
|
-
if (frame) cancelAnimationFrame(frame);
|
|
2948
|
-
document.removeEventListener("pointermove", move);
|
|
2949
|
-
document.documentElement.removeEventListener("pointerleave", leave);
|
|
2950
|
-
window.removeEventListener("blur", leave);
|
|
2951
|
-
clear();
|
|
2952
|
-
};
|
|
2953
|
-
}
|
|
2954
|
-
return () => {
|
|
2955
|
-
if (--users === 0) {
|
|
2956
|
-
cleanup?.();
|
|
2957
|
-
cleanup = void 0;
|
|
2958
|
-
}
|
|
2959
|
-
};
|
|
2960
|
-
}, []);
|
|
2961
|
-
}
|
|
2962
|
-
|
|
2963
|
-
// src/components/FloatingScrollbarProvider.tsx
|
|
2964
|
-
var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
2965
|
-
var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
|
|
2966
|
-
function isRootScroller(target) {
|
|
2967
|
-
return target === document.scrollingElement || target === document.documentElement;
|
|
2968
|
-
}
|
|
2969
|
-
function canScroll(target, axis) {
|
|
2970
|
-
if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
|
|
2971
|
-
if (isRootScroller(target)) {
|
|
2972
|
-
return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
2973
|
-
}
|
|
2974
|
-
const style = getComputedStyle(target);
|
|
2975
|
-
const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
|
|
2976
|
-
const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
2977
|
-
return hasOverflow && scrollableOverflow.has(overflow);
|
|
2978
|
-
}
|
|
2979
|
-
function visibleRect(target) {
|
|
2980
|
-
if (isRootScroller(target)) {
|
|
2981
|
-
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
2982
|
-
}
|
|
2983
|
-
const ownRect = target.getBoundingClientRect();
|
|
2984
|
-
let top = Math.max(0, ownRect.top);
|
|
2985
|
-
let right = Math.min(window.innerWidth, ownRect.right);
|
|
2986
|
-
let bottom = Math.min(window.innerHeight, ownRect.bottom);
|
|
2987
|
-
let left = Math.max(0, ownRect.left);
|
|
2988
|
-
let parent = target.parentElement;
|
|
2989
|
-
while (parent && parent !== document.body && parent !== document.documentElement) {
|
|
2990
|
-
const style = getComputedStyle(parent);
|
|
2991
|
-
const clipX = clippingOverflow.has(style.overflowX);
|
|
2992
|
-
const clipY = clippingOverflow.has(style.overflowY);
|
|
2993
|
-
if (clipX || clipY) {
|
|
2994
|
-
const rect = parent.getBoundingClientRect();
|
|
2995
|
-
if (clipX) {
|
|
2996
|
-
left = Math.max(left, rect.left);
|
|
2997
|
-
right = Math.min(right, rect.right);
|
|
2998
|
-
}
|
|
2999
|
-
if (clipY) {
|
|
3000
|
-
top = Math.max(top, rect.top);
|
|
3001
|
-
bottom = Math.min(bottom, rect.bottom);
|
|
3002
|
-
}
|
|
3003
|
-
}
|
|
3004
|
-
parent = parent.parentElement;
|
|
3005
|
-
}
|
|
3006
|
-
return {
|
|
3007
|
-
top,
|
|
3008
|
-
right,
|
|
3009
|
-
bottom,
|
|
3010
|
-
left,
|
|
3011
|
-
width: Math.max(0, right - left),
|
|
3012
|
-
height: Math.max(0, bottom - top)
|
|
3013
|
-
};
|
|
3014
|
-
}
|
|
3015
|
-
function createTrack(axis) {
|
|
3016
|
-
const track = document.createElement("div");
|
|
3017
|
-
const thumb = document.createElement("div");
|
|
3018
|
-
track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
|
|
3019
|
-
thumb.className = "sia-floating-scrollbar__thumb";
|
|
3020
|
-
track.dataset.axis = axis;
|
|
3021
|
-
track.setAttribute("aria-hidden", "true");
|
|
3022
|
-
track.append(thumb);
|
|
3023
|
-
return { track, thumb };
|
|
3024
|
-
}
|
|
3025
|
-
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
3026
|
-
useScrollbarProximity();
|
|
3027
|
-
(0, import_react15.useEffect)(() => {
|
|
3028
|
-
if (disabled) return;
|
|
3029
|
-
const layer = document.createElement("div");
|
|
3030
|
-
layer.className = "sia-floating-scrollbar-layer";
|
|
3031
|
-
layer.setAttribute("aria-hidden", "true");
|
|
3032
|
-
document.body.append(layer);
|
|
3033
|
-
const entries = /* @__PURE__ */ new Map();
|
|
3034
|
-
let scanFrame = 0;
|
|
3035
|
-
let updateFrame = 0;
|
|
3036
|
-
const setEntryVisible = (entry, visible) => {
|
|
3037
|
-
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
3038
|
-
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
3039
|
-
};
|
|
3040
|
-
const showEntry = (entry) => {
|
|
3041
|
-
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3042
|
-
entry.hideTimer = null;
|
|
3043
|
-
setEntryVisible(entry, true);
|
|
3044
|
-
};
|
|
3045
|
-
const scheduleHide = (entry, delay = 500) => {
|
|
3046
|
-
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3047
|
-
entry.hideTimer = window.setTimeout(() => {
|
|
3048
|
-
entry.hideTimer = null;
|
|
3049
|
-
if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
|
|
3050
|
-
}, delay);
|
|
3051
|
-
};
|
|
3052
|
-
const updateEntry = (entry) => {
|
|
3053
|
-
const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
|
|
3054
|
-
const hasHorizontal = canScroll(target, "horizontal");
|
|
3055
|
-
const hasVertical = canScroll(target, "vertical");
|
|
3056
|
-
const rect = visibleRect(target);
|
|
3057
|
-
const thickness = 10;
|
|
3058
|
-
horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
|
|
3059
|
-
verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
|
|
3060
|
-
if (!horizontalTrack.hidden) {
|
|
3061
|
-
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
3062
|
-
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
3063
|
-
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
3064
|
-
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
3065
|
-
horizontalTrack.style.left = `${rect.left}px`;
|
|
3066
|
-
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
3067
|
-
horizontalTrack.style.width = `${trackWidth}px`;
|
|
3068
|
-
horizontalTrack.style.height = `${thickness}px`;
|
|
3069
|
-
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
3070
|
-
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
3215
|
+
if (!event.target.closest(".sia-checkbox")) toggle(option);
|
|
3216
|
+
},
|
|
3217
|
+
children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "sia-selection-panel__text", children: [
|
|
3218
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
3219
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { children: String(option.value) })
|
|
3220
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "sia-selection-panel__text", children: [
|
|
3221
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
3222
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { children: String(option.value) })
|
|
3223
|
+
] })
|
|
3224
|
+
}
|
|
3225
|
+
) }, `${typeof option.value}-${option.value}`))
|
|
3226
|
+
},
|
|
3227
|
+
row.key
|
|
3228
|
+
)) })
|
|
3071
3229
|
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3230
|
+
)
|
|
3231
|
+
] });
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
// src/components/OverflowTags.tsx
|
|
3235
|
+
var import_react15 = require("react");
|
|
3236
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3237
|
+
function OverflowTags({ items, maxCount, className = "", tagClassName, restClassName = "" }) {
|
|
3238
|
+
const rootRef = (0, import_react15.useRef)(null);
|
|
3239
|
+
const measureRef = (0, import_react15.useRef)(null);
|
|
3240
|
+
const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount) || 0));
|
|
3241
|
+
const [visibleCount, setVisibleCount] = (0, import_react15.useState)(0);
|
|
3242
|
+
(0, import_react15.useLayoutEffect)(() => {
|
|
3243
|
+
const root = rootRef.current;
|
|
3244
|
+
const measure = measureRef.current;
|
|
3245
|
+
if (!root || !measure) return;
|
|
3246
|
+
const update = () => {
|
|
3247
|
+
const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
|
|
3248
|
+
const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
|
|
3249
|
+
let used = 0;
|
|
3250
|
+
let fitting = 0;
|
|
3251
|
+
for (let count2 = 1; count2 <= limit; count2 += 1) {
|
|
3252
|
+
used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
|
|
3253
|
+
const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
|
|
3254
|
+
if (used + rest <= root.clientWidth) fitting = count2;
|
|
3083
3255
|
}
|
|
3256
|
+
setVisibleCount((previous) => previous === fitting ? previous : fitting);
|
|
3084
3257
|
};
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
const trackRect = track.getBoundingClientRect();
|
|
3107
|
-
const thumbRect = thumb.getBoundingClientRect();
|
|
3108
|
-
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
3109
|
-
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
3110
|
-
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
3111
|
-
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
3112
|
-
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
3113
|
-
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
3114
|
-
};
|
|
3115
|
-
const onThumbPointerDown = (event) => {
|
|
3116
|
-
if (event.button !== 0) return;
|
|
3117
|
-
event.preventDefault();
|
|
3118
|
-
event.stopPropagation();
|
|
3119
|
-
entry.dragging = true;
|
|
3120
|
-
showEntry(entry);
|
|
3121
|
-
thumb.setPointerCapture(event.pointerId);
|
|
3122
|
-
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
3123
|
-
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
3124
|
-
const trackRect = track.getBoundingClientRect();
|
|
3125
|
-
const thumbRect = thumb.getBoundingClientRect();
|
|
3126
|
-
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
3127
|
-
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
3128
|
-
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
3129
|
-
const travel = Math.max(1, trackLength - thumbLength);
|
|
3130
|
-
const onPointerMove = (moveEvent) => {
|
|
3131
|
-
if (moveEvent.pointerId !== event.pointerId) return;
|
|
3132
|
-
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
3133
|
-
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
3134
|
-
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
3135
|
-
else target.scrollLeft = nextScroll;
|
|
3136
|
-
};
|
|
3137
|
-
const onPointerUp = (upEvent) => {
|
|
3138
|
-
if (upEvent.pointerId !== event.pointerId) return;
|
|
3139
|
-
entry.dragging = false;
|
|
3140
|
-
thumb.releasePointerCapture(event.pointerId);
|
|
3141
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
3142
|
-
window.removeEventListener("pointerup", onPointerUp);
|
|
3143
|
-
window.removeEventListener("pointercancel", onPointerUp);
|
|
3144
|
-
scheduleHide(entry);
|
|
3145
|
-
};
|
|
3146
|
-
window.addEventListener("pointermove", onPointerMove);
|
|
3147
|
-
window.addEventListener("pointerup", onPointerUp);
|
|
3148
|
-
window.addEventListener("pointercancel", onPointerUp);
|
|
3149
|
-
};
|
|
3150
|
-
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
3151
|
-
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
3152
|
-
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
3153
|
-
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
3154
|
-
return () => {
|
|
3155
|
-
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
3156
|
-
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
3157
|
-
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
3158
|
-
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
3159
|
-
};
|
|
3160
|
-
};
|
|
3161
|
-
const resizeObserver = new ResizeObserver((observedEntries) => {
|
|
3162
|
-
observedEntries.forEach(({ target }) => {
|
|
3163
|
-
const entry = entries.get(target);
|
|
3164
|
-
if (entry) updateEntry(entry);
|
|
3165
|
-
});
|
|
3166
|
-
});
|
|
3167
|
-
const addTarget = (target) => {
|
|
3168
|
-
if (entries.has(target)) return;
|
|
3169
|
-
const horizontal = createTrack("horizontal");
|
|
3170
|
-
const vertical = createTrack("vertical");
|
|
3171
|
-
layer.append(horizontal.track, vertical.track);
|
|
3172
|
-
const onPointerEnter = () => {
|
|
3173
|
-
const entry2 = entries.get(target);
|
|
3174
|
-
if (!entry2) return;
|
|
3175
|
-
entry2.hoveringTarget = true;
|
|
3176
|
-
showEntry(entry2);
|
|
3177
|
-
};
|
|
3178
|
-
const onPointerLeave = () => {
|
|
3179
|
-
const entry2 = entries.get(target);
|
|
3180
|
-
if (!entry2) return;
|
|
3181
|
-
entry2.hoveringTarget = false;
|
|
3182
|
-
scheduleHide(entry2);
|
|
3183
|
-
};
|
|
3184
|
-
const onScroll = () => {
|
|
3185
|
-
const entry2 = entries.get(target);
|
|
3186
|
-
if (!entry2) return;
|
|
3187
|
-
updateEntry(entry2);
|
|
3188
|
-
showEntry(entry2);
|
|
3189
|
-
scheduleHide(entry2, 700);
|
|
3190
|
-
};
|
|
3191
|
-
target.addEventListener("pointerenter", onPointerEnter);
|
|
3192
|
-
target.addEventListener("pointerleave", onPointerLeave);
|
|
3193
|
-
target.addEventListener("scroll", onScroll, { passive: true });
|
|
3194
|
-
const entry = {
|
|
3195
|
-
target,
|
|
3196
|
-
horizontalTrack: horizontal.track,
|
|
3197
|
-
horizontalThumb: horizontal.thumb,
|
|
3198
|
-
verticalTrack: vertical.track,
|
|
3199
|
-
verticalThumb: vertical.thumb,
|
|
3200
|
-
hideTimer: null,
|
|
3201
|
-
hoveringTarget: target.matches(":hover"),
|
|
3202
|
-
hoveringTrack: false,
|
|
3203
|
-
dragging: false,
|
|
3204
|
-
cleanup: () => void 0
|
|
3205
|
-
};
|
|
3206
|
-
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
3207
|
-
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
3208
|
-
entry.cleanup = () => {
|
|
3209
|
-
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3210
|
-
cleanupHorizontal();
|
|
3211
|
-
cleanupVertical();
|
|
3212
|
-
target.removeEventListener("pointerenter", onPointerEnter);
|
|
3213
|
-
target.removeEventListener("pointerleave", onPointerLeave);
|
|
3214
|
-
target.removeEventListener("scroll", onScroll);
|
|
3215
|
-
resizeObserver.unobserve(target);
|
|
3216
|
-
target.removeAttribute("data-sia-floating-scrollbar");
|
|
3217
|
-
horizontal.track.remove();
|
|
3218
|
-
vertical.track.remove();
|
|
3219
|
-
};
|
|
3220
|
-
entries.set(target, entry);
|
|
3221
|
-
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
3222
|
-
resizeObserver.observe(target);
|
|
3223
|
-
updateEntry(entry);
|
|
3224
|
-
if (entry.hoveringTarget) showEntry(entry);
|
|
3225
|
-
};
|
|
3226
|
-
const removeTarget = (target) => {
|
|
3227
|
-
const entry = entries.get(target);
|
|
3228
|
-
if (!entry) return;
|
|
3229
|
-
entry.cleanup();
|
|
3230
|
-
entries.delete(target);
|
|
3231
|
-
};
|
|
3232
|
-
const scanTargets = () => {
|
|
3233
|
-
scanFrame = 0;
|
|
3234
|
-
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
3235
|
-
const nextTargets = /* @__PURE__ */ new Set();
|
|
3236
|
-
candidates.forEach((target) => {
|
|
3237
|
-
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
3238
|
-
nextTargets.add(target);
|
|
3239
|
-
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
3240
|
-
}
|
|
3241
|
-
});
|
|
3242
|
-
entries.forEach((_entry, target) => {
|
|
3243
|
-
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
3244
|
-
else updateEntry(_entry);
|
|
3245
|
-
});
|
|
3246
|
-
};
|
|
3247
|
-
const scheduleScan = () => {
|
|
3248
|
-
if (scanFrame) return;
|
|
3249
|
-
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
3250
|
-
};
|
|
3251
|
-
const mutationObserver = new MutationObserver((mutations) => {
|
|
3252
|
-
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
3253
|
-
});
|
|
3254
|
-
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
3255
|
-
window.addEventListener("resize", scheduleScan);
|
|
3256
|
-
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
3257
|
-
scheduleScan();
|
|
3258
|
-
return () => {
|
|
3259
|
-
mutationObserver.disconnect();
|
|
3260
|
-
resizeObserver.disconnect();
|
|
3261
|
-
window.removeEventListener("resize", scheduleScan);
|
|
3262
|
-
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
3263
|
-
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
3264
|
-
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
3265
|
-
entries.forEach((entry) => entry.cleanup());
|
|
3266
|
-
entries.clear();
|
|
3267
|
-
layer.remove();
|
|
3268
|
-
};
|
|
3269
|
-
}, [disabled, targetRef]);
|
|
3270
|
-
return null;
|
|
3258
|
+
update();
|
|
3259
|
+
const observer = new ResizeObserver(update);
|
|
3260
|
+
observer.observe(root);
|
|
3261
|
+
for (const child of measure.children) observer.observe(child);
|
|
3262
|
+
return () => observer.disconnect();
|
|
3263
|
+
}, [items, limit]);
|
|
3264
|
+
const count = Math.min(visibleCount, limit);
|
|
3265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
|
|
3266
|
+
items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
3267
|
+
items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
|
|
3268
|
+
"+",
|
|
3269
|
+
items.length - count
|
|
3270
|
+
] }) : null,
|
|
3271
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
|
|
3272
|
+
items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
3273
|
+
Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
|
|
3274
|
+
"+",
|
|
3275
|
+
items.length - index
|
|
3276
|
+
] }, `rest-${index}`))
|
|
3277
|
+
] })
|
|
3278
|
+
] });
|
|
3271
3279
|
}
|
|
3272
3280
|
|
|
3273
3281
|
// src/components/Select.tsx
|
|
@@ -3332,6 +3340,8 @@ var Select = (0, import_react16.forwardRef)(function Select2({
|
|
|
3332
3340
|
const [query, setQuery] = (0, import_react16.useState)("");
|
|
3333
3341
|
const [activeIndex, setActiveIndex] = (0, import_react16.useState)(-1);
|
|
3334
3342
|
const [scrollTop, setScrollTop] = (0, import_react16.useState)(0);
|
|
3343
|
+
const [dropdownFontSize, setDropdownFontSize] = (0, import_react16.useState)();
|
|
3344
|
+
const pendingSelectedScroll = (0, import_react16.useRef)(false);
|
|
3335
3345
|
const deferredQuery = (0, import_react16.useDeferredValue)(query.trim());
|
|
3336
3346
|
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
3337
3347
|
const [currentValue, setCurrentValue] = useControllableState({
|
|
@@ -3389,10 +3399,31 @@ var Select = (0, import_react16.forwardRef)(function Select2({
|
|
|
3389
3399
|
(0, import_react16.useEffect)(() => {
|
|
3390
3400
|
if (disabled || loading) closeDropdown();
|
|
3391
3401
|
}, [disabled, loading]);
|
|
3402
|
+
(0, import_react16.useEffect)(() => {
|
|
3403
|
+
if (!open || popupMode !== "dropdown" || !pendingSelectedScroll.current || query) return;
|
|
3404
|
+
const index = filteredOptions.findIndex((option) => selectedValueSet.has(option.value));
|
|
3405
|
+
if (index < 0) return;
|
|
3406
|
+
const frame = requestAnimationFrame(() => {
|
|
3407
|
+
const list = listRef.current;
|
|
3408
|
+
if (!list) return;
|
|
3409
|
+
const item = virtualEnabled ? null : list.querySelectorAll('[role="option"]')[index];
|
|
3410
|
+
const top = virtualEnabled ? index * optionHeight : item ? item.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop : 0;
|
|
3411
|
+
list.scrollTop = Math.max(0, top - (list.clientHeight - (item?.offsetHeight ?? optionHeight)) / 2);
|
|
3412
|
+
setScrollTop(list.scrollTop);
|
|
3413
|
+
pendingSelectedScroll.current = false;
|
|
3414
|
+
});
|
|
3415
|
+
return () => cancelAnimationFrame(frame);
|
|
3416
|
+
}, [open, popupMode, filteredOptions, selectedValueSet, virtualEnabled, optionHeight, query]);
|
|
3417
|
+
(0, import_react16.useLayoutEffect)(() => {
|
|
3418
|
+
if (!open || popupMode !== "dropdown") return;
|
|
3419
|
+
const trigger = rootRef.current?.querySelector(".sia-select__trigger");
|
|
3420
|
+
if (trigger) setDropdownFontSize(getComputedStyle(trigger).fontSize);
|
|
3421
|
+
}, [open, popupMode, size]);
|
|
3392
3422
|
function firstEnabledIndex() {
|
|
3393
3423
|
return filteredOptions.findIndex((option) => !option.disabled);
|
|
3394
3424
|
}
|
|
3395
3425
|
function closeDropdown() {
|
|
3426
|
+
pendingSelectedScroll.current = false;
|
|
3396
3427
|
setOpen(false);
|
|
3397
3428
|
setQuery("");
|
|
3398
3429
|
setScrollTop(0);
|
|
@@ -3417,6 +3448,7 @@ var Select = (0, import_react16.forwardRef)(function Select2({
|
|
|
3417
3448
|
}
|
|
3418
3449
|
function openDropdown() {
|
|
3419
3450
|
if (disabled || loading) return;
|
|
3451
|
+
pendingSelectedScroll.current = true;
|
|
3420
3452
|
setOpenedMode(automaticMode);
|
|
3421
3453
|
const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
|
|
3422
3454
|
setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
|
|
@@ -3591,7 +3623,7 @@ var Select = (0, import_react16.forwardRef)(function Select2({
|
|
|
3591
3623
|
}
|
|
3592
3624
|
),
|
|
3593
3625
|
allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
3594
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
|
|
3626
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", style: { fontSize: dropdownFontSize }, className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
|
|
3595
3627
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FloatingScrollbarProvider, { targetRef: listRef }),
|
|
3596
3628
|
showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "sia-select__search", children: [
|
|
3597
3629
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "search", size: 15 }),
|