@udi-organization/udi-package 1.0.42 → 1.0.44

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.cjs.js CHANGED
@@ -2444,6 +2444,685 @@ var UdiTable = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
2444
2444
  });
2445
2445
  UdiTable.displayName = "UdiTable";
2446
2446
 
2447
+ /**
2448
+ * 開發環境日誌工具
2449
+ * 僅在開發環境下輸出訊息
2450
+ */
2451
+
2452
+ var devError = function devError(message) {
2453
+ if (process.env.NODE_ENV === 'development' || typeof process === 'undefined') {
2454
+ var _console;
2455
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2456
+ args[_key - 1] = arguments[_key];
2457
+ }
2458
+ (_console = console).error.apply(_console, ["[DevError] ".concat(message)].concat(args));
2459
+ }
2460
+ };
2461
+
2462
+ // 用於支援需要兩個表格以內同步的情況(執行較快)
2463
+ // 之後可能全面改用mutiple table版本,目前保留此程式碼以備用
2464
+
2465
+ /*
2466
+ const { mounted } = useUdiTableSync({
2467
+ importedTableRef,
2468
+ originalTableRef,
2469
+ enabled: open,
2470
+ syncScroll: true, // 同步滾動
2471
+ syncPagination: true, // 同步分頁
2472
+ paginationDeps: [tablePage], // 分頁相關依賴項
2473
+ });
2474
+ */
2475
+
2476
+ /**
2477
+ * 節流函數
2478
+ */
2479
+ var throttle$1 = function throttle(func, wait) {
2480
+ var timeout = null;
2481
+ var previous = 0;
2482
+ var throttled = function throttled() {
2483
+ var _this = this;
2484
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2485
+ args[_key] = arguments[_key];
2486
+ }
2487
+ var now = Date.now();
2488
+ var remaining = wait - (now - previous);
2489
+ if (remaining <= 0 || remaining > wait) {
2490
+ if (timeout) {
2491
+ clearTimeout(timeout);
2492
+ timeout = null;
2493
+ }
2494
+ previous = now;
2495
+ func.apply(this, args);
2496
+ } else if (!timeout) {
2497
+ timeout = setTimeout(function () {
2498
+ previous = Date.now();
2499
+ timeout = null;
2500
+ func.apply(_this, args);
2501
+ }, remaining);
2502
+ }
2503
+ };
2504
+ throttled.cancel = function () {
2505
+ if (timeout) {
2506
+ clearTimeout(timeout);
2507
+ timeout = null;
2508
+ }
2509
+ previous = 0;
2510
+ };
2511
+ return throttled;
2512
+ };
2513
+
2514
+ /**
2515
+ * 控制滾動同步的內部 Hook
2516
+ */
2517
+ var useControlScroll = function useControlScroll() {
2518
+ var rafId = React.useRef(null);
2519
+ return React.useCallback(function (sourceRef, targetRef) {
2520
+ // 取消上一次的動畫幀
2521
+ if (rafId.current) {
2522
+ cancelAnimationFrame(rafId.current);
2523
+ }
2524
+ rafId.current = requestAnimationFrame(function () {
2525
+ var _source$getScrollStat, _source$getState;
2526
+ var source = sourceRef === null || sourceRef === void 0 ? void 0 : sourceRef.current;
2527
+ var target = targetRef === null || targetRef === void 0 ? void 0 : targetRef.current;
2528
+ if (!source || !target) return;
2529
+ var scrollState = (_source$getScrollStat = source.getScrollState) === null || _source$getScrollStat === void 0 ? void 0 : _source$getScrollStat.call(source);
2530
+ var _ref = ((_source$getState = source.getState) === null || _source$getState === void 0 ? void 0 : _source$getState.call(source)) || {},
2531
+ isHovered = _ref.isHovered;
2532
+ if (!isHovered || !scrollState || !target.scrollControl) return;
2533
+ var top = scrollState.top,
2534
+ left = scrollState.left;
2535
+ target.scrollControl("top", top);
2536
+ target.scrollControl("left", left);
2537
+ });
2538
+ }, []);
2539
+ };
2540
+
2541
+ /**
2542
+ * 控制分頁同步的內部函數
2543
+ */
2544
+ var controlPagination = function controlPagination(sourceRef, targetRef) {
2545
+ if (!(sourceRef !== null && sourceRef !== void 0 && sourceRef.current) || !(targetRef !== null && targetRef !== void 0 && targetRef.current)) return false;
2546
+ var sourceState = sourceRef.current.getState();
2547
+ if (!sourceState.isHovered) return false;
2548
+ var sourcePagination = sourceState.pagination;
2549
+ var targetState = targetRef.current.getState();
2550
+ if (!targetState.pagination) return false;
2551
+ var targetPagination = targetState.pagination;
2552
+ var updated = false;
2553
+ if (sourcePagination.currentPage !== targetPagination.currentPage) {
2554
+ targetRef.current.setPage(sourcePagination.currentPage);
2555
+ updated = true;
2556
+ }
2557
+ if (sourcePagination.pageSize !== targetPagination.pageSize) {
2558
+ targetRef.current.setPageSize(sourcePagination.pageSize);
2559
+ updated = true;
2560
+ }
2561
+ return updated;
2562
+ };
2563
+
2564
+ /**
2565
+ * UDI 表格同步 Hook
2566
+ * @param {Object} options - 配置選項
2567
+ * @param {React.RefObject} options.importedTableRef - 導入表格的 ref
2568
+ * @param {React.RefObject} options.originalTableRef - 原始表格的 ref
2569
+ * @param {boolean} options.enabled - 是否啟用同步(預設: true)
2570
+ * @param {boolean} options.syncScroll - 是否同步滾動(預設: true)
2571
+ * @param {boolean} options.syncPagination - 是否同步分頁(預設: false)
2572
+ * @param {Array} options.paginationDeps - 分頁依賴項(預設: [])
2573
+ * @param {number} options.maxRetries - 最大重試次數(預設: 10)
2574
+ * @param {number} options.retryInterval - 重試間隔 ms(預設: 500)
2575
+ * @param {number} options.correctionDelay - 延遲修正時間 ms(預設: 200)
2576
+ * @param {number} options.throttleMs - 節流時間 ms(預設: 10)
2577
+ */
2578
+ var useUdiTableSync$1 = function useUdiTableSync() {
2579
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2580
+ var importedTableRef = options.importedTableRef,
2581
+ originalTableRef = options.originalTableRef,
2582
+ _options$enabled = options.enabled,
2583
+ enabled = _options$enabled === void 0 ? true : _options$enabled,
2584
+ _options$syncScroll = options.syncScroll,
2585
+ syncScroll = _options$syncScroll === void 0 ? true : _options$syncScroll,
2586
+ _options$syncPaginati = options.syncPagination,
2587
+ syncPagination = _options$syncPaginati === void 0 ? false : _options$syncPaginati,
2588
+ _options$paginationDe = options.paginationDeps,
2589
+ paginationDeps = _options$paginationDe === void 0 ? [] : _options$paginationDe,
2590
+ _options$maxRetries = options.maxRetries,
2591
+ maxRetries = _options$maxRetries === void 0 ? 10 : _options$maxRetries,
2592
+ _options$retryInterva = options.retryInterval,
2593
+ retryInterval = _options$retryInterva === void 0 ? 500 : _options$retryInterva,
2594
+ _options$correctionDe = options.correctionDelay,
2595
+ correctionDelay = _options$correctionDe === void 0 ? 200 : _options$correctionDe,
2596
+ _options$throttleMs = options.throttleMs,
2597
+ throttleMs = _options$throttleMs === void 0 ? 10 : _options$throttleMs;
2598
+ var controlScroll = useControlScroll();
2599
+ var mountedRef = React.useRef(false);
2600
+
2601
+ // 分頁同步邏輯
2602
+ React.useEffect(function () {
2603
+ if (!enabled || !syncPagination) return;
2604
+ if (!importedTableRef.current || !originalTableRef.current) return;
2605
+
2606
+ // 雙向同步分頁
2607
+ controlPagination(importedTableRef, originalTableRef);
2608
+ controlPagination(originalTableRef, importedTableRef);
2609
+ }, [enabled, syncPagination, importedTableRef, originalTableRef].concat(_toConsumableArray(paginationDeps)));
2610
+ var handleTableMount = React.useCallback(function () {
2611
+ var _importedTableRef$cur, _originalTableRef$cur;
2612
+ var importedTableElement = importedTableRef === null || importedTableRef === void 0 || (_importedTableRef$cur = importedTableRef.current) === null || _importedTableRef$cur === void 0 ? void 0 : _importedTableRef$cur.getState().tableWrapperRef;
2613
+ var originalTableElement = originalTableRef === null || originalTableRef === void 0 || (_originalTableRef$cur = originalTableRef.current) === null || _originalTableRef$cur === void 0 ? void 0 : _originalTableRef$cur.getState().tableWrapperRef;
2614
+ if (!importedTableElement || !originalTableElement) {
2615
+ return null; // 返回 null 表示掛載失敗
2616
+ }
2617
+
2618
+ // 防止重複掛載
2619
+ if (mountedRef.current) {
2620
+ console.warn("表格已掛載,跳過重複掛載");
2621
+ return null;
2622
+ }
2623
+ mountedRef.current = true;
2624
+ var correctionTimer = null;
2625
+ var handleScroll = throttle$1(function (event) {
2626
+ var target = event.target;
2627
+ var isImported = target === importedTableElement;
2628
+ var sourceRef = isImported ? importedTableRef : originalTableRef;
2629
+ var targetRef = isImported ? originalTableRef : importedTableRef;
2630
+
2631
+ // 立即同步
2632
+ controlScroll(sourceRef, targetRef);
2633
+
2634
+ // 清除並設置延遲修正
2635
+ if (correctionTimer) {
2636
+ clearTimeout(correctionTimer);
2637
+ }
2638
+ correctionTimer = setTimeout(function () {
2639
+ controlScroll(sourceRef, targetRef);
2640
+ correctionTimer = null;
2641
+ }, correctionDelay);
2642
+ }, throttleMs);
2643
+
2644
+ // 綁定事件
2645
+ importedTableElement.addEventListener("scroll", handleScroll, {
2646
+ passive: true
2647
+ });
2648
+ originalTableElement.addEventListener("scroll", handleScroll, {
2649
+ passive: true
2650
+ });
2651
+
2652
+ // 返回清理函數
2653
+ return function () {
2654
+ var _handleScroll$cancel;
2655
+ mountedRef.current = false;
2656
+ if (correctionTimer) {
2657
+ clearTimeout(correctionTimer);
2658
+ }
2659
+ importedTableElement.removeEventListener("scroll", handleScroll);
2660
+ originalTableElement.removeEventListener("scroll", handleScroll);
2661
+ (_handleScroll$cancel = handleScroll.cancel) === null || _handleScroll$cancel === void 0 || _handleScroll$cancel.call(handleScroll);
2662
+ };
2663
+ }, [importedTableRef, originalTableRef, controlScroll, correctionDelay, throttleMs]);
2664
+
2665
+ // 統一的掛載邏輯(帶重試機制)- 僅用於滾動同步
2666
+ React.useEffect(function () {
2667
+ if (!enabled || !syncScroll) {
2668
+ return;
2669
+ }
2670
+ var cleanup = null;
2671
+ var retryTimer = null;
2672
+ var retryCount = 0;
2673
+ var _attemptMount = function attemptMount() {
2674
+ // 嘗試掛載
2675
+ cleanup = handleTableMount();
2676
+
2677
+ // 如果掛載失敗且未超過重試次數
2678
+ if (!cleanup && retryCount < maxRetries) {
2679
+ retryCount++;
2680
+ retryTimer = setTimeout(_attemptMount, retryInterval);
2681
+ } else if (!cleanup) {
2682
+ devError("表格掛載失敗,已達最大重試次數");
2683
+ }
2684
+ };
2685
+
2686
+ // 初始延遲,確保 DOM 已渲染
2687
+ retryTimer = setTimeout(_attemptMount, 100);
2688
+
2689
+ // 清理函數
2690
+ return function () {
2691
+ if (retryTimer) {
2692
+ clearTimeout(retryTimer);
2693
+ }
2694
+ if (cleanup) {
2695
+ cleanup();
2696
+ }
2697
+ };
2698
+ }, [handleTableMount, enabled, syncScroll, maxRetries, retryInterval]);
2699
+ return {
2700
+ mounted: mountedRef.current
2701
+ };
2702
+ };
2703
+
2704
+ // 用於支援需要兩個表格以上同步的情況(執行較慢)
2705
+
2706
+ /**
2707
+ const tables = [
2708
+ { id: "imported", ref: importedTableRef },
2709
+ { id: "original", ref: originalTableRef },
2710
+ ];
2711
+
2712
+ const { registeredCount, registeredTables } = useUdiTableSync({
2713
+ tables,
2714
+ enabled: showCompareTable,
2715
+ syncScroll: true, // 是否同步滾動
2716
+ syncPagination: true, // 是否同步分頁
2717
+ paginationDeps: [tablePage], // 分頁依賴項
2718
+ });
2719
+ */
2720
+
2721
+ /**
2722
+ * 節流函數
2723
+ */
2724
+ var throttle = function throttle(func, wait) {
2725
+ var timeout = null;
2726
+ var previous = 0;
2727
+ var throttled = function throttled() {
2728
+ var _this = this;
2729
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2730
+ args[_key] = arguments[_key];
2731
+ }
2732
+ var now = Date.now();
2733
+ var remaining = wait - (now - previous);
2734
+ if (remaining <= 0 || remaining > wait) {
2735
+ if (timeout) {
2736
+ clearTimeout(timeout);
2737
+ timeout = null;
2738
+ }
2739
+ previous = now;
2740
+ func.apply(this, args);
2741
+ } else if (!timeout) {
2742
+ timeout = setTimeout(function () {
2743
+ previous = Date.now();
2744
+ timeout = null;
2745
+ func.apply(_this, args);
2746
+ }, remaining);
2747
+ }
2748
+ };
2749
+ throttled.cancel = function () {
2750
+ if (timeout) {
2751
+ clearTimeout(timeout);
2752
+ timeout = null;
2753
+ }
2754
+ previous = 0;
2755
+ };
2756
+ return throttled;
2757
+ };
2758
+
2759
+ /**
2760
+ * 控制分頁同步
2761
+ */
2762
+ var syncPaginationBetweenTables = function syncPaginationBetweenTables(sourceRef, targetRefs) {
2763
+ if (!(sourceRef !== null && sourceRef !== void 0 && sourceRef.current)) return false;
2764
+ var sourceState = sourceRef.current.getState();
2765
+ if (!sourceState.isHovered || !sourceState.pagination) return false;
2766
+ var sourcePagination = sourceState.pagination;
2767
+ var updated = false;
2768
+ targetRefs.forEach(function (targetRef) {
2769
+ if (!(targetRef !== null && targetRef !== void 0 && targetRef.current)) return;
2770
+ var targetState = targetRef.current.getState();
2771
+ if (!targetState.pagination) return;
2772
+ var targetPagination = targetState.pagination;
2773
+ if (sourcePagination.currentPage !== targetPagination.currentPage) {
2774
+ targetRef.current.setPage(sourcePagination.currentPage);
2775
+ updated = true;
2776
+ }
2777
+ if (sourcePagination.pageSize !== targetPagination.pageSize) {
2778
+ targetRef.current.setPageSize(sourcePagination.pageSize);
2779
+ updated = true;
2780
+ }
2781
+ });
2782
+ return updated;
2783
+ };
2784
+
2785
+ /**
2786
+ * UDI 表格動態同步 Hook
2787
+ * @param {Object} options - 配置選項
2788
+ * @param {Array<{id: string, ref: React.RefObject}>} options.tables - 表格數組
2789
+ * @param {boolean} options.enabled - 是否啟用同步(預設: true)
2790
+ * @param {boolean} options.syncScroll - 是否同步滾動(預設: true)
2791
+ * @param {boolean} options.syncPagination - 是否同步分頁(預設: false)
2792
+ * @param {Array} options.paginationDeps - 分頁依賴項(預設: [])
2793
+ * @param {number} options.maxRetries - 最大重試次數(預設: 10)
2794
+ * @param {number} options.retryInterval - 重試間隔 ms(預設: 500)
2795
+ * @param {number} options.correctionDelay - 延遲修正時間 ms(預設: 200)
2796
+ * @param {number} options.throttleMs - 節流時間 ms(預設: 10)
2797
+ */
2798
+ var useUdiTableSync = function useUdiTableSync() {
2799
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2800
+ var _options$tables = options.tables,
2801
+ tables = _options$tables === void 0 ? [] : _options$tables,
2802
+ _options$enabled = options.enabled,
2803
+ enabled = _options$enabled === void 0 ? true : _options$enabled,
2804
+ _options$syncScroll = options.syncScroll,
2805
+ syncScroll = _options$syncScroll === void 0 ? true : _options$syncScroll,
2806
+ _options$syncPaginati = options.syncPagination,
2807
+ syncPagination = _options$syncPaginati === void 0 ? true : _options$syncPaginati,
2808
+ _options$paginationDe = options.paginationDeps,
2809
+ paginationDeps = _options$paginationDe === void 0 ? [] : _options$paginationDe,
2810
+ _options$maxRetries = options.maxRetries,
2811
+ maxRetries = _options$maxRetries === void 0 ? 10 : _options$maxRetries,
2812
+ _options$retryInterva = options.retryInterval,
2813
+ retryInterval = _options$retryInterva === void 0 ? 500 : _options$retryInterva,
2814
+ _options$correctionDe = options.correctionDelay,
2815
+ correctionDelay = _options$correctionDe === void 0 ? 200 : _options$correctionDe,
2816
+ _options$throttleMs = options.throttleMs,
2817
+ throttleMs = _options$throttleMs === void 0 ? 10 : _options$throttleMs;
2818
+
2819
+ //如果tables沒有給id則自動補上id
2820
+ tables.forEach(function (table, index) {
2821
+ if (!table.id) {
2822
+ table.id = "table_".concat(index + 1);
2823
+ }
2824
+ });
2825
+ // 存儲所有已註冊的表格
2826
+ var registeredTablesRef = React.useRef(new Map());
2827
+ // 存儲滾動處理函數
2828
+ var handlersRef = React.useRef(new Map());
2829
+ // 存儲修正 timer
2830
+ var timersRef = React.useRef(new Map());
2831
+ // RAF ID
2832
+ var rafIdRef = React.useRef(null);
2833
+ // 防止循環同步的鎖
2834
+ var isSyncingRef = React.useRef(false);
2835
+
2836
+ /**
2837
+ * 分頁同步邏輯 - 處理所有表格的分頁同步
2838
+ */
2839
+ React.useEffect(function () {
2840
+ if (!enabled || !syncPagination || tables.length < 2) return;
2841
+
2842
+ // 檢查所有表格的 ref 是否存在
2843
+ var allRefsValid = tables.every(function (table) {
2844
+ var _table$ref;
2845
+ return (_table$ref = table.ref) === null || _table$ref === void 0 ? void 0 : _table$ref.current;
2846
+ });
2847
+ if (!allRefsValid) return;
2848
+
2849
+ // 找出當前 hover 的表格
2850
+ var hoveredTable = tables.find(function (table) {
2851
+ var _table$ref2;
2852
+ var state = (_table$ref2 = table.ref) === null || _table$ref2 === void 0 || (_table$ref2 = _table$ref2.current) === null || _table$ref2 === void 0 ? void 0 : _table$ref2.getState();
2853
+ return state === null || state === void 0 ? void 0 : state.isHovered;
2854
+ });
2855
+ if (!hoveredTable) return;
2856
+
2857
+ // 獲取其他所有表格的 refs
2858
+ var otherRefs = tables.filter(function (table) {
2859
+ return table.id !== hoveredTable.id;
2860
+ }).map(function (table) {
2861
+ return table.ref;
2862
+ });
2863
+
2864
+ // 同步分頁
2865
+ syncPaginationBetweenTables(hoveredTable.ref, otherRefs);
2866
+ }, [enabled, syncPagination, tables].concat(_toConsumableArray(paginationDeps)));
2867
+
2868
+ /**
2869
+ * 同步滾動位置到其他所有表格
2870
+ */
2871
+ var syncToOthers = React.useCallback(function (sourceId) {
2872
+ if (!enabled || !syncScroll || isSyncingRef.current) return;
2873
+ var sourceTable = registeredTablesRef.current.get(sourceId);
2874
+ if (!sourceTable) return;
2875
+
2876
+ // 取消上一次的 RAF
2877
+ if (rafIdRef.current) {
2878
+ cancelAnimationFrame(rafIdRef.current);
2879
+ }
2880
+ rafIdRef.current = requestAnimationFrame(function () {
2881
+ var _source$getScrollStat, _source$getState;
2882
+ isSyncingRef.current = true;
2883
+ var ref = sourceTable.ref;
2884
+ var source = ref === null || ref === void 0 ? void 0 : ref.current;
2885
+ if (!source) {
2886
+ isSyncingRef.current = false;
2887
+ return;
2888
+ }
2889
+
2890
+ // 獲取滾動狀態
2891
+ var scrollState = (_source$getScrollStat = source.getScrollState) === null || _source$getScrollStat === void 0 ? void 0 : _source$getScrollStat.call(source);
2892
+ var _ref = ((_source$getState = source.getState) === null || _source$getState === void 0 ? void 0 : _source$getState.call(source)) || {},
2893
+ isHovered = _ref.isHovered;
2894
+ if (!isHovered || !scrollState) {
2895
+ isSyncingRef.current = false;
2896
+ return;
2897
+ }
2898
+ var top = scrollState.top,
2899
+ left = scrollState.left;
2900
+
2901
+ // 同步到所有其他表格
2902
+ registeredTablesRef.current.forEach(function (targetTable, targetId) {
2903
+ var _targetTable$ref;
2904
+ if (targetId === sourceId) return; // 跳過源表格
2905
+
2906
+ var target = (_targetTable$ref = targetTable.ref) === null || _targetTable$ref === void 0 ? void 0 : _targetTable$ref.current;
2907
+ if (!target || !target.scrollControl) return;
2908
+ target.scrollControl("top", top);
2909
+ target.scrollControl("left", left);
2910
+ });
2911
+
2912
+ // 下一幀釋放鎖
2913
+ requestAnimationFrame(function () {
2914
+ isSyncingRef.current = false;
2915
+ });
2916
+ });
2917
+ }, [enabled, syncScroll]);
2918
+
2919
+ /**
2920
+ * 註冊單個表格
2921
+ */
2922
+ var registerTable = React.useCallback(function (id, ref) {
2923
+ var _ref$current;
2924
+ if (!enabled || !syncScroll) {
2925
+ console.warn("滾動同步未啟用");
2926
+ return false;
2927
+ }
2928
+
2929
+ // 檢查是否已註冊
2930
+ if (registeredTablesRef.current.has(id)) {
2931
+ console.warn("\u8868\u683C ".concat(id, " \u5DF2\u7D93\u8A3B\u518A\u904E\u4E86"));
2932
+ return false;
2933
+ }
2934
+ var element = ref === null || ref === void 0 || (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.getState().tableWrapperRef;
2935
+ if (!element) {
2936
+ console.error("\u8868\u683C ".concat(id, " \u7684 DOM \u5143\u7D20\u4E0D\u5B58\u5728"));
2937
+ return false;
2938
+ }
2939
+
2940
+ // 創建滾動處理函數
2941
+ var handleScroll = throttle(function () {
2942
+ // 立即同步
2943
+ syncToOthers(id);
2944
+
2945
+ // 清除之前的修正 timer
2946
+ var existingTimer = timersRef.current.get(id);
2947
+ if (existingTimer) {
2948
+ clearTimeout(existingTimer);
2949
+ }
2950
+
2951
+ // 設置延遲修正
2952
+ var correctionTimer = setTimeout(function () {
2953
+ syncToOthers(id);
2954
+ timersRef.current["delete"](id);
2955
+ }, correctionDelay);
2956
+ timersRef.current.set(id, correctionTimer);
2957
+ }, throttleMs);
2958
+
2959
+ // 綁定事件
2960
+ element.addEventListener("scroll", handleScroll, {
2961
+ passive: true
2962
+ });
2963
+
2964
+ // 存儲表格信息
2965
+ registeredTablesRef.current.set(id, {
2966
+ ref: ref,
2967
+ element: element
2968
+ });
2969
+ handlersRef.current.set(id, handleScroll);
2970
+ return true;
2971
+ }, [enabled, syncScroll, syncToOthers, correctionDelay, throttleMs]);
2972
+
2973
+ /**
2974
+ * 註銷單個表格
2975
+ */
2976
+ var unregisterTable = React.useCallback(function (id) {
2977
+ var table = registeredTablesRef.current.get(id);
2978
+ if (!table) return false;
2979
+ var handler = handlersRef.current.get(id);
2980
+ var timer = timersRef.current.get(id);
2981
+
2982
+ // 清理 timer
2983
+ if (timer) {
2984
+ clearTimeout(timer);
2985
+ timersRef.current["delete"](id);
2986
+ }
2987
+
2988
+ // 解綁事件
2989
+ if (handler) {
2990
+ var _handler$cancel;
2991
+ table.element.removeEventListener("scroll", handler);
2992
+ (_handler$cancel = handler.cancel) === null || _handler$cancel === void 0 || _handler$cancel.call(handler);
2993
+ handlersRef.current["delete"](id);
2994
+ }
2995
+
2996
+ // 移除表格
2997
+ registeredTablesRef.current["delete"](id);
2998
+ return true;
2999
+ }, []);
3000
+
3001
+ /**
3002
+ * 帶重試機制的註冊
3003
+ */
3004
+ var registerWithRetry = React.useCallback(function (id, ref) {
3005
+ var retryCount = 0;
3006
+ var retryTimer = null;
3007
+ var _attemptRegister = function attemptRegister() {
3008
+ var success = registerTable(id, ref);
3009
+ if (!success && retryCount < maxRetries) {
3010
+ retryCount++;
3011
+ retryTimer = setTimeout(_attemptRegister, retryInterval);
3012
+ }
3013
+ };
3014
+
3015
+ // 初始延遲,確保 DOM 已渲染
3016
+ retryTimer = setTimeout(_attemptRegister, 100);
3017
+
3018
+ // 返回清理函數
3019
+ return function () {
3020
+ if (retryTimer) {
3021
+ clearTimeout(retryTimer);
3022
+ }
3023
+ unregisterTable(id);
3024
+ };
3025
+ }, [registerTable, unregisterTable, maxRetries, retryInterval]);
3026
+
3027
+ /**
3028
+ * 註冊所有表格(滾動同步)
3029
+ */
3030
+ React.useEffect(function () {
3031
+ if (!enabled || !syncScroll || tables.length === 0) {
3032
+ return;
3033
+ }
3034
+ var cleanups = [];
3035
+
3036
+ // 註冊所有表格
3037
+ tables.forEach(function (_ref2) {
3038
+ var id = _ref2.id,
3039
+ ref = _ref2.ref;
3040
+ var cleanup = registerWithRetry(id, ref);
3041
+ cleanups.push(cleanup);
3042
+ });
3043
+
3044
+ // 清理函數
3045
+ return function () {
3046
+ cleanups.forEach(function (cleanup) {
3047
+ return cleanup === null || cleanup === void 0 ? void 0 : cleanup();
3048
+ });
3049
+ };
3050
+ }, [tables, enabled, syncScroll, registerWithRetry]);
3051
+
3052
+ /**
3053
+ * 組件卸載時清理所有資源
3054
+ */
3055
+ React.useEffect(function () {
3056
+ return function () {
3057
+ // 取消 RAF
3058
+ if (rafIdRef.current) {
3059
+ cancelAnimationFrame(rafIdRef.current);
3060
+ }
3061
+
3062
+ // 清理所有 timer
3063
+ timersRef.current.forEach(function (timer) {
3064
+ clearTimeout(timer);
3065
+ });
3066
+ timersRef.current.clear();
3067
+
3068
+ // 清理所有事件監聽器
3069
+ registeredTablesRef.current.forEach(function (table, id) {
3070
+ var handler = handlersRef.current.get(id);
3071
+ if (handler) {
3072
+ var _handler$cancel2;
3073
+ table.element.removeEventListener("scroll", handler);
3074
+ (_handler$cancel2 = handler.cancel) === null || _handler$cancel2 === void 0 || _handler$cancel2.call(handler);
3075
+ }
3076
+ });
3077
+ registeredTablesRef.current.clear();
3078
+ handlersRef.current.clear();
3079
+ };
3080
+ }, []);
3081
+
3082
+ /**
3083
+ * 獲取已註冊的表格列表
3084
+ */
3085
+ var getRegisteredTables = React.useCallback(function () {
3086
+ return Array.from(registeredTablesRef.current.keys());
3087
+ }, []);
3088
+
3089
+ /**
3090
+ * 手動觸發滾動同步
3091
+ */
3092
+ var manualSync = React.useCallback(function (sourceId) {
3093
+ if (syncScroll) {
3094
+ syncToOthers(sourceId);
3095
+ }
3096
+ }, [syncToOthers, syncScroll]);
3097
+
3098
+ /**
3099
+ * 手動觸發分頁同步
3100
+ */
3101
+ var manualSyncPagination = React.useCallback(function () {
3102
+ if (!syncPagination || tables.length < 2) return;
3103
+ var hoveredTable = tables.find(function (table) {
3104
+ var _table$ref3;
3105
+ var state = (_table$ref3 = table.ref) === null || _table$ref3 === void 0 || (_table$ref3 = _table$ref3.current) === null || _table$ref3 === void 0 ? void 0 : _table$ref3.getState();
3106
+ return state === null || state === void 0 ? void 0 : state.isHovered;
3107
+ });
3108
+ if (!hoveredTable) return;
3109
+ var otherRefs = tables.filter(function (table) {
3110
+ return table.id !== hoveredTable.id;
3111
+ }).map(function (table) {
3112
+ return table.ref;
3113
+ });
3114
+ syncPaginationBetweenTables(hoveredTable.ref, otherRefs);
3115
+ }, [syncPagination, tables]);
3116
+ return {
3117
+ registeredTables: getRegisteredTables(),
3118
+ registeredCount: registeredTablesRef.current.size,
3119
+ registerTable: registerWithRetry,
3120
+ unregisterTable: unregisterTable,
3121
+ manualSync: manualSync,
3122
+ manualSyncPagination: manualSyncPagination
3123
+ };
3124
+ };
3125
+
2447
3126
  function greet(name) {
2448
3127
  return "Hello, ".concat(name, "! 105");
2449
3128
  }
@@ -2455,4 +3134,6 @@ exports.Button = Button;
2455
3134
  exports.UdiTable = UdiTable;
2456
3135
  exports.add = add;
2457
3136
  exports.greet = greet;
3137
+ exports.useUdiTableSync = useUdiTableSync$1;
3138
+ exports.useUdiTableSyncMutipleTable = useUdiTableSync;
2458
3139
  //# sourceMappingURL=index.cjs.js.map