seeder-st2110-components 1.6.0 → 1.6.1

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
3
+ var React = require('react');
4
4
  var antd = require('antd');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var ahooks = require('ahooks');
@@ -80,7 +80,7 @@ const formatBytes = function (bytes) {
80
80
  const i = Math.floor(Math.log(bytes) / Math.log(k));
81
81
  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
82
82
  };
83
- const UsageItem = /*#__PURE__*/react.memo(_ref => {
83
+ const UsageItem = /*#__PURE__*/React.memo(_ref => {
84
84
  let {
85
85
  title,
86
86
  iconClass,
@@ -110,8 +110,8 @@ const UsageItem = /*#__PURE__*/react.memo(_ref => {
110
110
  var UsageItem$1 = UsageItem;
111
111
 
112
112
  const useHardwareWebSocket = socketUrl => {
113
- const [systemStatus, setSystemStatus] = react.useState();
114
- const handleMessage = react.useCallback(message => {
113
+ const [systemStatus, setSystemStatus] = React.useState();
114
+ const handleMessage = React.useCallback(message => {
115
115
  try {
116
116
  if (message) {
117
117
  setSystemStatus(prev => _objectSpread2(_objectSpread2({}, prev), message));
@@ -234,7 +234,7 @@ const useHardwareUsage = socketUrl => {
234
234
  const {
235
235
  ps_status
236
236
  } = useHardwareWebSocket$1(socketUrl);
237
- return react.useMemo(() => {
237
+ return React.useMemo(() => {
238
238
  if (!ps_status || typeof ps_status !== 'object') return null;
239
239
  const statusItems = getItems(getDetail(ps_status));
240
240
  return /*#__PURE__*/jsxRuntime.jsx("div", {
@@ -266,7 +266,7 @@ const AuthorizationModal = _ref => {
266
266
  const {
267
267
  message
268
268
  } = antd.App.useApp();
269
- const [code, setCode] = react.useState('');
269
+ const [code, setCode] = React.useState('');
270
270
  const {
271
271
  accredit_status: isActivated,
272
272
  message: statusMessage = 'Unactivated',
@@ -360,13 +360,13 @@ const useAuth = options => {
360
360
  autoShowModal = true
361
361
  } = options || {};
362
362
  const [messageApi, contextHolder] = antd.message.useMessage();
363
- const [showModal, setShowModal] = react.useState(false); // 默认隐藏
364
- const [authData, setAuthData] = react.useState(defaultAuthData);
365
- const [isRegistered, setIsRegistered] = react.useState(false);
366
- const [loading, setLoading] = react.useState(false);
367
- const openModal = react.useCallback(() => setShowModal(true), []);
368
- const closeModal = react.useCallback(() => setShowModal(false), []);
369
- react.useEffect(() => {
363
+ const [showModal, setShowModal] = React.useState(false); // 默认隐藏
364
+ const [authData, setAuthData] = React.useState(defaultAuthData);
365
+ const [isRegistered, setIsRegistered] = React.useState(false);
366
+ const [loading, setLoading] = React.useState(false);
367
+ const openModal = React.useCallback(() => setShowModal(true), []);
368
+ const closeModal = React.useCallback(() => setShowModal(false), []);
369
+ React.useEffect(() => {
370
370
  async function loadAuthInfo() {
371
371
  try {
372
372
  setLoading(true);
@@ -442,22 +442,22 @@ const useUpgrade = _ref => {
442
442
  uploadCompleteDelay = 3000,
443
443
  statusPollingInterval = 1000
444
444
  } = _ref;
445
- const [isSpinning, setIsSpinning] = react.useState(false);
446
- const [interval, setInterval] = react.useState(undefined); // 间隔时间,当设置值为 undefined 时会停止计时器
447
- const inputRef = react.useRef(null);
448
- const [currentStatus, setCurrentStatus] = react.useState('idle'); // 'idle' | 'uploading' | 'upgrading'
449
- const isUploadCompleteRef = react.useRef(false); // 安装包上传是否完成
450
- const [uploadProgress, setUploadProgress] = react.useState(0);
445
+ const [isSpinning, setIsSpinning] = React.useState(false);
446
+ const [interval, setInterval] = React.useState(undefined); // 间隔时间,当设置值为 undefined 时会停止计时器
447
+ const inputRef = React.useRef(null);
448
+ const [currentStatus, setCurrentStatus] = React.useState('idle'); // 'idle' | 'uploading' | 'upgrading'
449
+ const isUploadCompleteRef = React.useRef(false); // 安装包上传是否完成
450
+ const [uploadProgress, setUploadProgress] = React.useState(0);
451
451
 
452
452
  // 分别创建独立的取消令牌
453
- const uploadCancelToken = react.useRef(axios.CancelToken.source());
454
- const statusCancelToken = react.useRef(axios.CancelToken.source());
453
+ const uploadCancelToken = React.useRef(axios.CancelToken.source());
454
+ const statusCancelToken = React.useRef(axios.CancelToken.source());
455
455
  const showLoader = () => setIsSpinning(true);
456
456
  const hideLoader = () => setIsSpinning(false);
457
457
 
458
458
  // 构建菜单项 - 确保至少包含download和upload
459
459
  // 构建菜单项 - 最终完美版本
460
- const finalMenuItems = react.useMemo(() => {
460
+ const finalMenuItems = React.useMemo(() => {
461
461
  const hasDownload = menuItems.some(item => item.key === 'download');
462
462
  const hasUpload = menuItems.some(item => item.key === 'upload');
463
463
  if (hasDownload && hasUpload) {
@@ -694,7 +694,7 @@ const useUpgrade = _ref => {
694
694
  ahooks.useInterval(fetchUpgradeStatus, interval);
695
695
 
696
696
  // 组件卸载时清理
697
- react.useEffect(() => {
697
+ React.useEffect(() => {
698
698
  return () => {
699
699
  uploadCancelToken.current.cancel();
700
700
  statusCancelToken.current.cancel();
@@ -748,7 +748,7 @@ const useSystemOperations = function () {
748
748
  const {
749
749
  modal: AntdModal
750
750
  } = antd.App.useApp();
751
- const doAction = react.useCallback(action => {
751
+ const doAction = React.useCallback(action => {
752
752
  try {
753
753
  AntdModal.confirm({
754
754
  icon: /*#__PURE__*/jsxRuntime.jsx(icons.ExclamationCircleFilled, {}),
@@ -772,14 +772,14 @@ const useSystemOperations = function () {
772
772
  console.error("".concat(action.toUpperCase(), " ERROR: "), error);
773
773
  }
774
774
  }, [AntdModal, confirmTitle, cancelText, okText, onPowerOff, onRestart]);
775
- const getMenuItems = react.useCallback(() => [{
775
+ const getMenuItems = React.useCallback(() => [{
776
776
  key: "poweroff",
777
777
  label: "Power Off"
778
778
  }, {
779
779
  key: "restart",
780
780
  label: "Restart"
781
781
  }], []);
782
- const handleMenuClick = react.useCallback(_ref => {
782
+ const handleMenuClick = React.useCallback(_ref => {
783
783
  let {
784
784
  key
785
785
  } = _ref;
@@ -881,15 +881,15 @@ const NetworkSettingsModal = _ref2 => {
881
881
  modal
882
882
  } = antd.App.useApp();
883
883
  const [form] = antd.Form.useForm();
884
- const [st2110Interfaces, setSt2110Interfaces] = react.useState([]);
885
- const [lanConfigs, setLanConfigs] = react.useState([]);
886
- const [submitLoading, setSubmitLoading] = react.useState(false);
887
- const [isInitialized, setIsInitialized] = react.useState(false);
888
- const initializationStatus = react.useRef({
884
+ const [st2110Interfaces, setSt2110Interfaces] = React.useState([]);
885
+ const [lanConfigs, setLanConfigs] = React.useState([]);
886
+ const [submitLoading, setSubmitLoading] = React.useState(false);
887
+ const [isInitialized, setIsInitialized] = React.useState(false);
888
+ const initializationStatus = React.useRef({
889
889
  hasFetched: false,
890
890
  hasInitialized: false
891
891
  });
892
- const preparedFieldConfig = react.useMemo(() => {
892
+ const preparedFieldConfig = React.useMemo(() => {
893
893
  const config = _objectSpread2({}, fieldConfig);
894
894
 
895
895
  // 确保LAN和QSFP的配置存在
@@ -907,7 +907,7 @@ const NetworkSettingsModal = _ref2 => {
907
907
  }
908
908
  return config;
909
909
  }, [fieldConfig, showNetmask, sections]);
910
- react.useEffect(() => {
910
+ React.useEffect(() => {
911
911
  if (!open) return;
912
912
  const fetchData = async () => {
913
913
  if (initializationStatus.current.hasFetched) return;
@@ -954,7 +954,7 @@ const NetworkSettingsModal = _ref2 => {
954
954
  }, [open, getLanConfig, getSysConfig, sections]);
955
955
 
956
956
  // 当模态框关闭时重置状态
957
- react.useEffect(() => {
957
+ React.useEffect(() => {
958
958
  if (!open) {
959
959
  setIsInitialized(false);
960
960
  setLanConfigs([]);
@@ -968,7 +968,7 @@ const NetworkSettingsModal = _ref2 => {
968
968
  }, [open, form]);
969
969
 
970
970
  // 动态初始值配置
971
- const initialValues = react.useMemo(() => {
971
+ const initialValues = React.useMemo(() => {
972
972
  const values = {};
973
973
  if (sections.includes('LAN') && lanConfigs.length > 0) {
974
974
  values.LAN = lanConfigs.map(config => _objectSpread2({
@@ -993,13 +993,13 @@ const NetworkSettingsModal = _ref2 => {
993
993
  }, [lanConfigs, st2110Interfaces, sections, showNetmask]);
994
994
 
995
995
  // 当初始值准备好后设置表单值
996
- react.useEffect(() => {
996
+ React.useEffect(() => {
997
997
  if (isInitialized && !initializationStatus.current.hasInitialized) {
998
998
  form.setFieldsValue(initialValues);
999
999
  initializationStatus.current.hasInitialized = true;
1000
1000
  }
1001
1001
  }, [isInitialized, form, initialValues]);
1002
- const handleSuccess = react.useCallback(async function () {
1002
+ const handleSuccess = React.useCallback(async function () {
1003
1003
  let {
1004
1004
  messageText = 'Success',
1005
1005
  isPopup = !!restart,
@@ -1039,7 +1039,7 @@ const NetworkSettingsModal = _ref2 => {
1039
1039
  }
1040
1040
  onClose();
1041
1041
  }, [message, modal, getSysConfig, restart, getConfig, sections, onClose]);
1042
- const handleSubmit = react.useCallback(async () => {
1042
+ const handleSubmit = React.useCallback(async () => {
1043
1043
  setSubmitLoading(true);
1044
1044
  try {
1045
1045
  const values = await form.validateFields();
@@ -1150,7 +1150,7 @@ const NetworkSettingsModal = _ref2 => {
1150
1150
  })), restartRemark]
1151
1151
  }));
1152
1152
  };
1153
- var NetworkSettingsModal$1 = /*#__PURE__*/react.memo(NetworkSettingsModal);
1153
+ var NetworkSettingsModal$1 = /*#__PURE__*/React.memo(NetworkSettingsModal);
1154
1154
 
1155
1155
  const defaultFieldConfigs = {
1156
1156
  clock_class: {
@@ -1276,12 +1276,12 @@ const PtpModal = _ref => {
1276
1276
  modalProps = {},
1277
1277
  formProps = {}
1278
1278
  } = _ref;
1279
- const [ptpStatus, setPtpStatus] = react.useState(null);
1279
+ const [ptpStatus, setPtpStatus] = React.useState(null);
1280
1280
  const [form] = antd.Form.useForm();
1281
1281
  const {
1282
1282
  message
1283
1283
  } = antd.App.useApp();
1284
- react.useEffect(() => {
1284
+ React.useEffect(() => {
1285
1285
  if (open) {
1286
1286
  getPtpInfo().then(data => {
1287
1287
  if (data !== null && data !== void 0 && data[0]) {
@@ -1291,7 +1291,7 @@ const PtpModal = _ref => {
1291
1291
  });
1292
1292
  }
1293
1293
  }, [open, form, getPtpInfo]);
1294
- const ptpStatusArray = react.useMemo(() => {
1294
+ const ptpStatusArray = React.useMemo(() => {
1295
1295
  if (!ptpStatus) return [];
1296
1296
  return convertPtpStatusToArray(ptpStatus, fieldConfigs, fieldOrder);
1297
1297
  }, [ptpStatus]);
@@ -1396,9 +1396,9 @@ const PtpModal = _ref => {
1396
1396
  }))
1397
1397
  }));
1398
1398
  };
1399
- var PtpModal$1 = /*#__PURE__*/react.memo(PtpModal);
1399
+ var PtpModal$1 = /*#__PURE__*/React.memo(PtpModal);
1400
1400
 
1401
- const LeftList = /*#__PURE__*/react.memo(_ref => {
1401
+ const LeftList = /*#__PURE__*/React.memo(_ref => {
1402
1402
  let {
1403
1403
  dataSource,
1404
1404
  selectedPresetId,
@@ -1515,7 +1515,7 @@ const SubmitButton = _ref2 => {
1515
1515
  })
1516
1516
  });
1517
1517
  };
1518
- const RightDetailForm = /*#__PURE__*/react.memo(_ref3 => {
1518
+ const RightDetailForm = /*#__PURE__*/React.memo(_ref3 => {
1519
1519
  let {
1520
1520
  form,
1521
1521
  onSave,
@@ -1536,14 +1536,14 @@ const RightDetailForm = /*#__PURE__*/react.memo(_ref3 => {
1536
1536
  },
1537
1537
  presetChanged
1538
1538
  } = _ref3;
1539
- const [initialSelected, setInitialSelected] = react.useState([]);
1539
+ const [initialSelected, setInitialSelected] = React.useState([]);
1540
1540
  const currentSelected = antd.Form.useWatch('category_list', form) || [];
1541
1541
 
1542
1542
  // 检查是否包含category_list字段
1543
1543
  const hasCategoryList = fields.category_list !== null && fields.category_list !== undefined;
1544
1544
 
1545
1545
  // 初始化 category_list 的选择状态
1546
- react.useEffect(() => {
1546
+ React.useEffect(() => {
1547
1547
  if (hasCategoryList) {
1548
1548
  const currentValue = form.getFieldValue('category_list') || [];
1549
1549
  setInitialSelected(currentValue);
@@ -1551,7 +1551,7 @@ const RightDetailForm = /*#__PURE__*/react.memo(_ref3 => {
1551
1551
  }, [presetChanged, form, hasCategoryList]); // 当presetChanged变化时更新
1552
1552
 
1553
1553
  // 动态生成 checkbox 选项
1554
- const checkboxOptions = react.useMemo(() => {
1554
+ const checkboxOptions = React.useMemo(() => {
1555
1555
  if (!hasCategoryList) return [];
1556
1556
  return fields.category_list.options.map(category => {
1557
1557
  const isInitiallySelected = initialSelected.includes(category.name);
@@ -1694,17 +1694,17 @@ const Preset = _ref => {
1694
1694
  message: AntdMessage,
1695
1695
  modal: AntdModal
1696
1696
  } = antd.App.useApp();
1697
- const [presetList, setPresetList] = react.useState([]);
1698
- const [selectedPreset, setSelectedPreset] = react.useState(null);
1699
- const [loading, setLoading] = react.useState(false);
1700
- const [presetChanged, setPresetChanged] = react.useState(0);
1697
+ const [presetList, setPresetList] = React.useState([]);
1698
+ const [selectedPreset, setSelectedPreset] = React.useState(null);
1699
+ const [loading, setLoading] = React.useState(false);
1700
+ const [presetChanged, setPresetChanged] = React.useState(0);
1701
1701
  const [form] = antd.Form.useForm();
1702
1702
 
1703
1703
  // 获取预设列表
1704
- react.useEffect(() => {
1704
+ React.useEffect(() => {
1705
1705
  fetchPresetList();
1706
1706
  }, []);
1707
- const fetchPresetList = react.useCallback(async () => {
1707
+ const fetchPresetList = React.useCallback(async () => {
1708
1708
  try {
1709
1709
  const data = await getPresetList();
1710
1710
  const presets = (data === null || data === void 0 ? void 0 : data.preset_list) || data || [];
@@ -1713,12 +1713,12 @@ const Preset = _ref => {
1713
1713
  console.error('Failed to fetch preset list:', error);
1714
1714
  }
1715
1715
  }, [getPresetList]);
1716
- const handleSelectPreset = react.useCallback(preset => {
1716
+ const handleSelectPreset = React.useCallback(preset => {
1717
1717
  setSelectedPreset(preset);
1718
1718
  form.setFieldsValue(preset);
1719
1719
  setPresetChanged(prev => prev + 1); // 触发react更新
1720
1720
  }, [form]);
1721
- const handleAddNew = react.useCallback(() => {
1721
+ const handleAddNew = React.useCallback(() => {
1722
1722
  var _fields$category_list;
1723
1723
  const unsavedPreset = presetList.find(item => !item.id);
1724
1724
  if (unsavedPreset) {
@@ -1740,7 +1740,7 @@ const Preset = _ref => {
1740
1740
  setSelectedPreset(newPreset);
1741
1741
  form.setFieldsValue(newPreset);
1742
1742
  }, [form, presetList, AntdMessage]);
1743
- const handleRemove = react.useCallback(async () => {
1743
+ const handleRemove = React.useCallback(async () => {
1744
1744
  if (!selectedPreset) return;
1745
1745
 
1746
1746
  // 检查是否为新建的未保存数据(无id)
@@ -1774,7 +1774,7 @@ const Preset = _ref => {
1774
1774
  console.error('Failed to delete preset:', error);
1775
1775
  }
1776
1776
  }, [selectedPreset, form, AntdModal, AntdMessage, fetchPresetList, texts]);
1777
- const handleLoadPreset = react.useCallback(async loadData => {
1777
+ const handleLoadPreset = React.useCallback(async loadData => {
1778
1778
  if (!loadData) return;
1779
1779
 
1780
1780
  // 显示确认对话框
@@ -1826,7 +1826,7 @@ const Preset = _ref => {
1826
1826
  }
1827
1827
  });
1828
1828
  }, [loadPreset, texts, AntdMessage, AntdModal, onLoadSuccess, onLoadError]);
1829
- const handleSave = react.useCallback(async () => {
1829
+ const handleSave = React.useCallback(async () => {
1830
1830
  setLoading(true);
1831
1831
  try {
1832
1832
  const values = await form.validateFields();
@@ -1913,9 +1913,9 @@ const Preset = _ref => {
1913
1913
  })
1914
1914
  });
1915
1915
  };
1916
- var PresetModal = /*#__PURE__*/react.memo(Preset);
1916
+ var PresetModal = /*#__PURE__*/React.memo(Preset);
1917
1917
 
1918
- const _excluded = ["menuItems", "onMenuClick", "downloadFiles", "upgradeExecute", "upgradeStatus", "acceptFileTypes", "uploadCompleteDelay", "statusPollingInterval", "children"];
1918
+ const _excluded$1 = ["menuItems", "onMenuClick", "downloadFiles", "upgradeExecute", "upgradeStatus", "acceptFileTypes", "uploadCompleteDelay", "statusPollingInterval", "children"];
1919
1919
  const UpgradeManager = _ref => {
1920
1920
  let {
1921
1921
  menuItems = [],
@@ -1928,7 +1928,7 @@ const UpgradeManager = _ref => {
1928
1928
  statusPollingInterval = 1000,
1929
1929
  children
1930
1930
  } = _ref,
1931
- dropdownProps = _objectWithoutProperties(_ref, _excluded);
1931
+ dropdownProps = _objectWithoutProperties(_ref, _excluded$1);
1932
1932
  const [upgradeElement] = useUpgrade$1({
1933
1933
  menuItems,
1934
1934
  onMenuClick,
@@ -3323,7 +3323,9 @@ const CommonHeader = _ref => {
3323
3323
  getSocketUrl = defaultGetSocketUrl,
3324
3324
  logoProps = {},
3325
3325
  className = '',
3326
- style = {}
3326
+ style = {},
3327
+ // 新增插槽
3328
+ leftContent // 左侧额外内容
3327
3329
  } = _ref;
3328
3330
  const [logo] = useSpaLogo$1(logoProps);
3329
3331
 
@@ -3353,7 +3355,7 @@ const CommonHeader = _ref => {
3353
3355
  },
3354
3356
  children: productInfo.version
3355
3357
  })]
3356
- })]
3358
+ }), leftContent]
3357
3359
  }), /*#__PURE__*/jsxRuntime.jsxs(antd.Flex, {
3358
3360
  align: "center",
3359
3361
  gap: 10,
@@ -3397,8 +3399,324 @@ CommonHeader.propTypes = {
3397
3399
  };
3398
3400
  var CommonHeader$1 = CommonHeader;
3399
3401
 
3402
+ const _excluded = ["value", "min", "max", "className", "disablePointerLock", "modifierKeys", "decimalPlaces", "onChange", "onDragStart", "onDragEnd", "style"];
3403
+
3404
+ // 默认配置
3405
+ const DEFAULT_DECIMAL_PLACES = 2;
3406
+
3407
+ // src/react/defaults-and-utils.ts
3408
+ // eslint-disable-next-line no-var
3409
+ var defaultModifiers = {
3410
+ default: {
3411
+ multiplier: 1,
3412
+ sensitivity: 1
3413
+ }
3414
+ // ctrlKey: { multiplier: 1, sensitivity: 1 },
3415
+ // shiftKey: { multiplier: 10, sensitivity: 0.5 },
3416
+ // metaKey: { multiplier: 1, sensitivity: 1 },
3417
+ // altKey: { multiplier: 1, sensitivity: 1 }
3418
+ };
3419
+
3420
+ // multiplier: 控制每次鼠标移动时数值变化的基本单位 multiplier: 1- 鼠标移动1像素,值变化1 multiplier: 10- 鼠标移动1像素,值变化10
3421
+ // sensitivity: 控制数值变化的灵敏度 sensitivity: 1- 正常灵敏度 sensitivity: 0.5- 减半灵敏度,需要移动2像素才能产生正常1像素的效果
3422
+
3423
+ // 修改 formatNumber 函数,强制显示1位小数
3424
+ function formatNumber(value) {
3425
+ let decimalPlaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_DECIMAL_PLACES;
3426
+ return new Intl.NumberFormat("en-US", {
3427
+ minimumFractionDigits: decimalPlaces,
3428
+ maximumFractionDigits: decimalPlaces,
3429
+ useGrouping: false
3430
+ }).format(value);
3431
+ }
3432
+ function handleArrow(e, multiplier, value) {
3433
+ if (e.key === "ArrowUp") {
3434
+ return value + multiplier;
3435
+ }
3436
+ if (e.key === "ArrowDown") {
3437
+ return value - multiplier;
3438
+ }
3439
+ return value;
3440
+ }
3441
+
3442
+ // eslint-disable-next-line no-var
3443
+ var DragCursor = _ref => {
3444
+ let {
3445
+ cursorPosition
3446
+ } = _ref;
3447
+ return /* @__PURE__ */React.createElement("div", {
3448
+ style: {
3449
+ position: "fixed",
3450
+ left: 0,
3451
+ top: 0,
3452
+ width: "100vw",
3453
+ height: "100vh",
3454
+ pointerEvents: "none"
3455
+ }
3456
+ }, /* @__PURE__ */React.createElement("svg", {
3457
+ xmlns: "http://www.w3.org/2000/svg",
3458
+ width: "24",
3459
+ height: "24",
3460
+ viewBox: "0 0 24 24",
3461
+ style: {
3462
+ position: "absolute",
3463
+ left: cursorPosition.x,
3464
+ top: cursorPosition.y,
3465
+ transform: "translate(-50%, -50%)",
3466
+ pointerEvents: "none"
3467
+ }
3468
+ }, /* @__PURE__ */React.createElement("path", {
3469
+ fill: "#000",
3470
+ stroke: "#fff",
3471
+ strokeLinejoin: "round",
3472
+ d: "M6.5 9a.5.5 0 0 0-.8-.4l-4 3a.5.5 0 0 0 0 .8l4 3a.5.5 0 0 0 .8-.4v-1.5h11V15a.5.5 0 0 0 .8.4l4-3a.5.5 0 0 0 0-.8l-4-3a.5.5 0 0 0-.8.4v1.5h-11V9Z",
3473
+ style: {
3474
+ filter: "drop-shadow( 0px 2px 1px rgba(0, 0, 0, .35))"
3475
+ }
3476
+ })));
3477
+ };
3478
+
3479
+ // eslint-disable-next-line no-var
3480
+ var noop = () => {};
3481
+ function DraggableNumberInput(_ref2) {
3482
+ let {
3483
+ value,
3484
+ min,
3485
+ max,
3486
+ className = "",
3487
+ disablePointerLock = false,
3488
+ modifierKeys,
3489
+ decimalPlaces = DEFAULT_DECIMAL_PLACES,
3490
+ onChange = noop,
3491
+ onDragStart = noop,
3492
+ onDragEnd = noop,
3493
+ style
3494
+ } = _ref2,
3495
+ restProps = _objectWithoutProperties(_ref2, _excluded);
3496
+ const inputRef = React.useRef(null);
3497
+ const [isMouseDown, setIsMouseDown] = React.useState(false);
3498
+ const [isDragging, setIsDragging] = React.useState(false);
3499
+ const [localValue, setLocalValue] = React.useState(() => formatNumber(value, decimalPlaces));
3500
+ const [cursorPosition, setCursorPosition] = React.useState({
3501
+ x: 0,
3502
+ y: 0
3503
+ });
3504
+ const totalMovement = React.useRef(0);
3505
+ const startValue = React.useRef(0);
3506
+ const startX = React.useRef(0);
3507
+ const currentMultiplier = React.useRef(1);
3508
+
3509
+ // === 新增:编辑状态跟踪 ===
3510
+ const [isEditing, setIsEditing] = React.useState(false);
3511
+ const lastExternalValueRef = React.useRef(value);
3512
+
3513
+ // 修改 formatNumber 调用,传入 decimalPlaces
3514
+ const formatValue = React.useCallback(val => {
3515
+ return formatNumber(val, decimalPlaces);
3516
+ }, [decimalPlaces]);
3517
+ const constrainedOnChange = React.useCallback(newValue => {
3518
+ let constrainedValue = newValue;
3519
+ if (typeof min === "number") {
3520
+ constrainedValue = Math.max(min, constrainedValue);
3521
+ }
3522
+ if (typeof max === "number") {
3523
+ constrainedValue = Math.min(max, constrainedValue);
3524
+ }
3525
+ onChange(constrainedValue);
3526
+ }, [onChange, min, max]);
3527
+ React.useEffect(() => {
3528
+ // 只有当用户不在编辑状态,且外部值真正变化时才更新
3529
+ if (!isEditing && lastExternalValueRef.current !== value) {
3530
+ const formattedValue = formatValue(value);
3531
+ setLocalValue(formattedValue);
3532
+ lastExternalValueRef.current = value;
3533
+ }
3534
+ }, [value, formatValue, isEditing]);
3535
+ const handleInputChange = e => {
3536
+ const val = e.target.value;
3537
+
3538
+ // 标记为编辑状态
3539
+ setIsEditing(true);
3540
+ setLocalValue(val);
3541
+
3542
+ // 允许输入中间状态,不立即触发onChange
3543
+ if (val === '' || val === '-' || val === '.' || val.endsWith('.')) {
3544
+ return; // 输入中,不触发onChange
3545
+ }
3546
+ const num = parseFloat(val);
3547
+ if (!isNaN(num)) {
3548
+ constrainedOnChange(num);
3549
+ }
3550
+ };
3551
+ const handleBlur = () => {
3552
+ // 退出编辑状态
3553
+ setIsEditing(false);
3554
+ const num = parseFloat(localValue);
3555
+ if (!isNaN(num)) {
3556
+ // 根据 decimalPlaces 进行四舍五入
3557
+ const precision = Math.pow(10, decimalPlaces);
3558
+ const processedValue = Math.round(num * precision) / precision;
3559
+ const formattedValue = formatValue(processedValue);
3560
+
3561
+ // 更新显示值
3562
+ setLocalValue(formattedValue);
3563
+ lastExternalValueRef.current = processedValue;
3564
+ // 触发外部变化
3565
+ constrainedOnChange(processedValue);
3566
+ } else {
3567
+ // 如果输入无效,重置为当前外部值
3568
+ const formattedValue = formatValue(value);
3569
+ setLocalValue(formattedValue);
3570
+ }
3571
+ };
3572
+ const handleMouseDown = React.useCallback(e => {
3573
+ if (!inputRef.current) return;
3574
+ let x = 0,
3575
+ y = 0;
3576
+ if ("clientX" in e && "clientY" in e) {
3577
+ [x, y] = [e.clientX, e.clientY];
3578
+ }
3579
+ if ("touches" in e) {
3580
+ [x, y] = [e.touches[0].clientX, e.touches[0].clientY];
3581
+ }
3582
+ setIsMouseDown(true);
3583
+ startX.current = x;
3584
+ startValue.current = value;
3585
+ totalMovement.current = 0;
3586
+ setCursorPosition({
3587
+ x,
3588
+ y
3589
+ });
3590
+ }, [value, disablePointerLock]);
3591
+ const updateDelta = React.useCallback(e => {
3592
+ if (!isMouseDown) return;
3593
+ applyMovement(totalMovement.current, e);
3594
+ }, [isMouseDown]);
3595
+ const getModifiers = React.useCallback(e => {
3596
+ const mods = _objectSpread2(_objectSpread2({}, defaultModifiers), modifierKeys);
3597
+ for (const key in mods) {
3598
+ if (key !== "default" && e[key]) {
3599
+ currentMultiplier.current = mods[key].multiplier;
3600
+ return mods[key];
3601
+ }
3602
+ }
3603
+ currentMultiplier.current = mods.default.multiplier;
3604
+ return mods.default;
3605
+ }, [modifierKeys]);
3606
+ const applyMovement = React.useCallback((newMovement, e) => {
3607
+ const {
3608
+ sensitivity,
3609
+ multiplier
3610
+ } = getModifiers(e);
3611
+ const delta = newMovement * sensitivity * multiplier;
3612
+ let newValue = startValue.current + delta;
3613
+ // 根据 decimalPlaces 进行精度控制
3614
+ const precision = Math.pow(10, decimalPlaces);
3615
+ newValue = Math.round(newValue * precision) / precision;
3616
+ newValue = Object.is(newValue, -0) ? 0 : newValue;
3617
+ constrainedOnChange(newValue);
3618
+ }, [constrainedOnChange, getModifiers, decimalPlaces]);
3619
+ const handleArrowKeyDown = e => {
3620
+ if (e.key === "ArrowUp" || e.key === "ArrowDown") {
3621
+ e.preventDefault();
3622
+ const {
3623
+ multiplier
3624
+ } = getModifiers(e);
3625
+ const newValue = handleArrow(e, multiplier, value);
3626
+ constrainedOnChange(newValue);
3627
+ }
3628
+ };
3629
+ const handleModifierKeyDuringDrag = React.useCallback(e => {
3630
+ if (e.key === "Shift" || e.key === "Control" || e.key === "Meta" || e.key === "Alt") {
3631
+ updateDelta(e);
3632
+ }
3633
+ }, [updateDelta]);
3634
+ const handleMouseMove = React.useCallback(e => {
3635
+ if (!isMouseDown) return;
3636
+ if ("touches" in e) {
3637
+ e.preventDefault();
3638
+ }
3639
+ if (!disablePointerLock && document.pointerLockElement && !("touches" in e)) {
3640
+ setCursorPosition(prev => {
3641
+ const width = window.innerWidth;
3642
+ const height = window.innerHeight;
3643
+ const x2 = (prev.x + e.movementX + width) % width;
3644
+ const y = (prev.y + e.movementY + height) % height;
3645
+ return {
3646
+ x: x2,
3647
+ y
3648
+ };
3649
+ });
3650
+ }
3651
+ const x = "touches" in e ? e.touches[0].clientX : e.clientX;
3652
+ const newMovement = disablePointerLock || "touches" in e ? x - startX.current : totalMovement.current + e.movementX;
3653
+ if (!isDragging && newMovement !== 0) {
3654
+ if (!disablePointerLock && !("touches" in e)) {
3655
+ var _inputRef$current, _inputRef$current$req;
3656
+ (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || (_inputRef$current$req = _inputRef$current.requestPointerLock) === null || _inputRef$current$req === void 0 || _inputRef$current$req.call(_inputRef$current);
3657
+ }
3658
+ setIsDragging(true);
3659
+ document.addEventListener("keydown", handleModifierKeyDuringDrag);
3660
+ document.addEventListener("keyup", handleModifierKeyDuringDrag);
3661
+ onDragStart();
3662
+ }
3663
+ totalMovement.current = newMovement;
3664
+ applyMovement(newMovement, e);
3665
+ }, [isMouseDown, disablePointerLock, startX, isDragging, onDragStart, applyMovement]);
3666
+ const handleMouseUp = React.useCallback(() => {
3667
+ setIsMouseDown(false);
3668
+ totalMovement.current = 0;
3669
+ if (isDragging) {
3670
+ setIsDragging(false);
3671
+ document.removeEventListener("keydown", handleModifierKeyDuringDrag);
3672
+ document.removeEventListener("keyup", handleModifierKeyDuringDrag);
3673
+ onDragEnd();
3674
+ }
3675
+ if (document.pointerLockElement) {
3676
+ document.exitPointerLock();
3677
+ }
3678
+ }, [isDragging, onDragEnd, disablePointerLock]);
3679
+ React.useEffect(() => {
3680
+ if (isMouseDown) {
3681
+ document.addEventListener("mousemove", handleMouseMove);
3682
+ document.addEventListener("touchmove", handleMouseMove, {
3683
+ passive: false
3684
+ });
3685
+ document.addEventListener("mouseup", handleMouseUp);
3686
+ document.addEventListener("touchend", handleMouseUp);
3687
+ return () => {
3688
+ document.removeEventListener("mousemove", handleMouseMove);
3689
+ document.removeEventListener("mouseup", handleMouseUp);
3690
+ document.removeEventListener("touchmove", handleMouseMove);
3691
+ document.removeEventListener("touchend", handleMouseUp);
3692
+ };
3693
+ }
3694
+ }, [isMouseDown, handleMouseMove, handleMouseUp]);
3695
+ return /* @__PURE__ */React.createElement(React.Fragment, null, /* @__PURE__ */React.createElement("input", _objectSpread2({
3696
+ ref: inputRef,
3697
+ type: "text",
3698
+ inputMode: "numeric",
3699
+ pattern: "-?[0-9]*\\.?[0-9]*",
3700
+ value: localValue,
3701
+ onChange: handleInputChange,
3702
+ onBlur: handleBlur,
3703
+ onMouseDown: handleMouseDown,
3704
+ onTouchStart: handleMouseDown,
3705
+ onKeyDown: handleArrowKeyDown,
3706
+ className: "draggable-number-input ".concat(className, " ").concat(isDragging ? "dragging" : ""),
3707
+ style: _objectSpread2(_objectSpread2({}, {
3708
+ cursor: "ew-resize",
3709
+ userSelect: "none",
3710
+ caretColor: isDragging ? "transparent" : "initial"
3711
+ }), style)
3712
+ }, restProps)), isDragging && !disablePointerLock && /* @__PURE__ */React.createElement(DragCursor, {
3713
+ cursorPosition
3714
+ }));
3715
+ }
3716
+
3400
3717
  exports.AuthorizationModal = AuthorizationModal$1;
3401
3718
  exports.CommonHeader = CommonHeader$1;
3719
+ exports.DraggableNumberInput = DraggableNumberInput;
3402
3720
  exports.NetworkSettingsModal = NetworkSettingsModal$1;
3403
3721
  exports.PresetModal = PresetModal;
3404
3722
  exports.PtpModal = PtpModal$1;