@yogiswara/honcho-editor-ui 2.5.9 → 2.5.10
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.
|
@@ -30,6 +30,8 @@ export declare function useHonchoEditorBulk(controller: Controller, eventID: str
|
|
|
30
30
|
handleBackCallbackBulk: () => void;
|
|
31
31
|
selectedBulkPreset: string;
|
|
32
32
|
handleToggleImageSelection: (imageId: string) => void;
|
|
33
|
+
handleLoadMore: () => Promise<void>;
|
|
34
|
+
handleRefresh: () => Promise<void>;
|
|
33
35
|
handleSelectBulkPreset: (event: SelectChangeEvent<string>) => void;
|
|
34
36
|
handleBulkTempDecreaseMax: () => void;
|
|
35
37
|
handleBulkTempDecrease: () => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
2
|
+
import { useState, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
3
|
import { useAdjustmentHistoryBatch } from '../useAdjustmentHistoryBatch';
|
|
4
|
+
import { usePaging } from "../usePaging";
|
|
4
5
|
// Helper function to map the API response to the format our UI component needs
|
|
5
6
|
const mapGalleryToPhotoData = (gallery, selectedIds) => {
|
|
6
7
|
return {
|
|
@@ -40,24 +41,36 @@ function mapColorAdjustmentToAdjustmentState(adj) {
|
|
|
40
41
|
}
|
|
41
42
|
export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
|
|
42
43
|
const { currentBatch, selectedIds, actions: batchActions } = useAdjustmentHistoryBatch();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
const [page, setPage] = useState(1);
|
|
48
|
-
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
49
|
-
const [hasMore, setHasMore] = useState(true);
|
|
44
|
+
const { images, info, actions } = usePaging(controller, firebaseUid, eventID);
|
|
45
|
+
// Track which images have been synced to prevent loops
|
|
46
|
+
const lastSyncedImageIds = useRef(new Set());
|
|
47
|
+
// State for Bulk Editing
|
|
50
48
|
const [selectedBulkPreset, setSelectedBulkPreset] = useState('preset1');
|
|
49
|
+
// Use loading states from usePaging instead of local state
|
|
50
|
+
const isLoading = info.isLoading;
|
|
51
|
+
const error = info.error;
|
|
52
|
+
const hasMore = info.hasMore;
|
|
51
53
|
const imageData = useMemo(() => {
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
console.log("adjustment FROM USEHONCHOBULK: ", adjustment);
|
|
58
|
-
return adjustment ? { ...item, ...adjustment } : item;
|
|
54
|
+
return images.map(item => {
|
|
55
|
+
const basePhoto = mapGalleryToPhotoData(item, selectedIds);
|
|
56
|
+
const batchAdjustment = currentBatch.allImages[item.id];
|
|
57
|
+
// Merge batch adjustments over backend adjustments
|
|
58
|
+
return batchAdjustment ? { ...basePhoto, ...batchAdjustment } : basePhoto;
|
|
59
59
|
});
|
|
60
|
-
}, [
|
|
60
|
+
}, [images, selectedIds, currentBatch.allImages]);
|
|
61
|
+
// Safe sync: Only sync new images to prevent infinite loops
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (images.length === 0)
|
|
64
|
+
return;
|
|
65
|
+
// Check if we have new images that haven't been synced
|
|
66
|
+
const currentImageIds = new Set(images.map(img => img.id));
|
|
67
|
+
const hasNewImages = images.some(img => !lastSyncedImageIds.current.has(img.id));
|
|
68
|
+
if (hasNewImages) {
|
|
69
|
+
console.log('[useHonchoEditorBulk] Syncing new images to batch:', images.length);
|
|
70
|
+
batchActions.syncAdjustment(images.map(mapToImageAdjustmentConfig));
|
|
71
|
+
lastSyncedImageIds.current = currentImageIds;
|
|
72
|
+
}
|
|
73
|
+
}, [images, batchActions]);
|
|
61
74
|
const handleBackCallbackBulk = useCallback(() => {
|
|
62
75
|
const lastSelectedId = selectedIds.length > 0 ? selectedIds[selectedIds.length - 1] : "";
|
|
63
76
|
controller.handleBack(firebaseUid, lastSelectedId);
|
|
@@ -148,26 +161,8 @@ export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
|
|
|
148
161
|
// loadImages(page + 1);
|
|
149
162
|
// }
|
|
150
163
|
// }, [isFetchingMore, hasMore, page, loadImages]);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
setIsLoading(true);
|
|
154
|
-
setError(null);
|
|
155
|
-
controller.getImageList(firebaseUid, eventID, 2)
|
|
156
|
-
.then(response => {
|
|
157
|
-
// TODO need do pagination for this one
|
|
158
|
-
batchActions.syncAdjustment(response.gallery.map(mapToImageAdjustmentConfig));
|
|
159
|
-
setImageCollection(response.gallery);
|
|
160
|
-
})
|
|
161
|
-
.catch(err => {
|
|
162
|
-
console.error("Failed to fetch image list:", err);
|
|
163
|
-
setError("Could not load images.");
|
|
164
|
-
})
|
|
165
|
-
.finally(() => {
|
|
166
|
-
setIsLoading(false);
|
|
167
|
-
});
|
|
168
|
-
console.log("Image data FROM USEHONCHOBULK: ", imageData);
|
|
169
|
-
}
|
|
170
|
-
}, [eventID, firebaseUid, controller]);
|
|
164
|
+
// Note: Image loading is now handled by usePaging hook
|
|
165
|
+
// The sync logic above handles syncing loaded images to batch state
|
|
171
166
|
// useEffect(() => {
|
|
172
167
|
// if (eventID && firebaseUid) {
|
|
173
168
|
// setImageCollection([]); // reset when event changes
|
|
@@ -186,6 +181,8 @@ export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
|
|
|
186
181
|
handleBackCallbackBulk,
|
|
187
182
|
selectedBulkPreset,
|
|
188
183
|
handleToggleImageSelection: batchActions.toggleSelection,
|
|
184
|
+
handleLoadMore: actions.loadMore,
|
|
185
|
+
handleRefresh: actions.refresh,
|
|
189
186
|
handleSelectBulkPreset,
|
|
190
187
|
// Adjustment
|
|
191
188
|
handleBulkTempDecreaseMax,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Gallery } from './editor/type';
|
|
2
|
+
import { Controller } from "./editor/useHonchoEditor";
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for the paging hook
|
|
5
|
+
*/
|
|
6
|
+
export interface PagingOptions {
|
|
7
|
+
/** Enable development warnings for debugging */
|
|
8
|
+
devWarnings?: boolean;
|
|
9
|
+
/** Auto-load first page on hook initialization */
|
|
10
|
+
autoLoad?: boolean;
|
|
11
|
+
/** Reset pagination when dependencies change */
|
|
12
|
+
autoReset?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Information about the current paging state
|
|
16
|
+
*/
|
|
17
|
+
export interface PagingInfo {
|
|
18
|
+
/** Whether images are currently being loaded */
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
/** Whether more pages are being loaded */
|
|
21
|
+
isLoadingMore: boolean;
|
|
22
|
+
/** Error message if any operation failed */
|
|
23
|
+
error: string | null;
|
|
24
|
+
/** Current page number */
|
|
25
|
+
currentPage: number;
|
|
26
|
+
/** Whether there are more pages to load */
|
|
27
|
+
hasMore: boolean;
|
|
28
|
+
/** Total number of images loaded */
|
|
29
|
+
totalImages: number;
|
|
30
|
+
/** Whether the hook has been initialized */
|
|
31
|
+
isInitialized: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Actions available for paging management
|
|
35
|
+
*/
|
|
36
|
+
export interface PagingActions {
|
|
37
|
+
/** Load more images (next page) - only one instance can run at a time */
|
|
38
|
+
loadMore: () => Promise<void>;
|
|
39
|
+
/** Refresh/reload from first page */
|
|
40
|
+
refresh: () => Promise<void>;
|
|
41
|
+
/** Reset pagination state */
|
|
42
|
+
reset: () => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Return type for the usePaging hook
|
|
46
|
+
*/
|
|
47
|
+
export interface UsePagingReturn {
|
|
48
|
+
/** Current list of images */
|
|
49
|
+
images: Gallery[];
|
|
50
|
+
/** Information about paging state */
|
|
51
|
+
info: PagingInfo;
|
|
52
|
+
/** Available paging actions */
|
|
53
|
+
actions: PagingActions;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Hook for managing paginated image loading with ControllerBulk.
|
|
57
|
+
*
|
|
58
|
+
* **Key Features:**
|
|
59
|
+
* - **Paginated Loading**: Handles page-by-page image loading
|
|
60
|
+
* - **State Management**: Maintains image list and pagination state
|
|
61
|
+
* - **Load More**: Seamlessly loads and appends next pages
|
|
62
|
+
* - **Mutation**: Update specific images without full reload
|
|
63
|
+
* - **Error Handling**: Provides error states for failed operations
|
|
64
|
+
* - **Auto-loading**: Optional automatic first page loading
|
|
65
|
+
*
|
|
66
|
+
* **Typical Usage:**
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const { images, info, actions } = usePaging(controller, firebaseUid, eventId, {
|
|
69
|
+
* autoLoad: true,
|
|
70
|
+
* autoReset: true
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* // Load more images
|
|
74
|
+
* await actions.loadMore();
|
|
75
|
+
*
|
|
76
|
+
* // Refresh from beginning
|
|
77
|
+
* await actions.refresh();
|
|
78
|
+
*
|
|
79
|
+
* // Update specific image
|
|
80
|
+
* actions.mutateImage(imageId, (img) => ({ ...img, isSelected: true }));
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @param controller - Backend controller for API communication
|
|
84
|
+
* @param firebaseUid - User identifier for backend operations
|
|
85
|
+
* @param eventId - Event identifier for image list
|
|
86
|
+
* @param options - Configuration options
|
|
87
|
+
* @returns Object with images, info, and actions
|
|
88
|
+
*/
|
|
89
|
+
export declare function usePaging(controller: Controller | null, firebaseUid: string, eventId: string, options?: PagingOptions): UsePagingReturn;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect, useRef, useMemo } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for managing paginated image loading with ControllerBulk.
|
|
4
|
+
*
|
|
5
|
+
* **Key Features:**
|
|
6
|
+
* - **Paginated Loading**: Handles page-by-page image loading
|
|
7
|
+
* - **State Management**: Maintains image list and pagination state
|
|
8
|
+
* - **Load More**: Seamlessly loads and appends next pages
|
|
9
|
+
* - **Mutation**: Update specific images without full reload
|
|
10
|
+
* - **Error Handling**: Provides error states for failed operations
|
|
11
|
+
* - **Auto-loading**: Optional automatic first page loading
|
|
12
|
+
*
|
|
13
|
+
* **Typical Usage:**
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const { images, info, actions } = usePaging(controller, firebaseUid, eventId, {
|
|
16
|
+
* autoLoad: true,
|
|
17
|
+
* autoReset: true
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Load more images
|
|
21
|
+
* await actions.loadMore();
|
|
22
|
+
*
|
|
23
|
+
* // Refresh from beginning
|
|
24
|
+
* await actions.refresh();
|
|
25
|
+
*
|
|
26
|
+
* // Update specific image
|
|
27
|
+
* actions.mutateImage(imageId, (img) => ({ ...img, isSelected: true }));
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @param controller - Backend controller for API communication
|
|
31
|
+
* @param firebaseUid - User identifier for backend operations
|
|
32
|
+
* @param eventId - Event identifier for image list
|
|
33
|
+
* @param options - Configuration options
|
|
34
|
+
* @returns Object with images, info, and actions
|
|
35
|
+
*/
|
|
36
|
+
export function usePaging(controller, firebaseUid, eventId, options = {}) {
|
|
37
|
+
// Memoize options to prevent re-renders when object is recreated with same values
|
|
38
|
+
const memoizedOptions = useMemo(() => ({
|
|
39
|
+
devWarnings: options.devWarnings ?? false,
|
|
40
|
+
autoLoad: options.autoLoad ?? false,
|
|
41
|
+
autoReset: options.autoReset ?? true
|
|
42
|
+
}), [options.devWarnings, options.autoLoad, options.autoReset]);
|
|
43
|
+
// Core state
|
|
44
|
+
const [images, setImages] = useState([]);
|
|
45
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
46
|
+
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
47
|
+
const [error, setError] = useState(null);
|
|
48
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
49
|
+
const [hasMore, setHasMore] = useState(true);
|
|
50
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
51
|
+
// Track if loadMore is currently running to prevent spam
|
|
52
|
+
const isLoadMoreRunningRef = useRef(false);
|
|
53
|
+
// Track dependencies with stable refs
|
|
54
|
+
const controllerRef = useRef(controller);
|
|
55
|
+
const firebaseUidRef = useRef(firebaseUid);
|
|
56
|
+
const eventIdRef = useRef(eventId);
|
|
57
|
+
// Only update refs when values actually change
|
|
58
|
+
if (controllerRef.current !== controller) {
|
|
59
|
+
controllerRef.current = controller;
|
|
60
|
+
}
|
|
61
|
+
if (firebaseUidRef.current !== firebaseUid) {
|
|
62
|
+
firebaseUidRef.current = firebaseUid;
|
|
63
|
+
}
|
|
64
|
+
if (eventIdRef.current !== eventId) {
|
|
65
|
+
eventIdRef.current = eventId;
|
|
66
|
+
}
|
|
67
|
+
// Helper function to log debug messages
|
|
68
|
+
const debugLog = useCallback((message, data) => {
|
|
69
|
+
if (memoizedOptions.devWarnings) {
|
|
70
|
+
console.log(`[usePaging] ${message}`, data || '');
|
|
71
|
+
}
|
|
72
|
+
}, [memoizedOptions.devWarnings]);
|
|
73
|
+
// Helper function to handle errors
|
|
74
|
+
const handleError = useCallback((operation, error) => {
|
|
75
|
+
const errorMessage = `Failed to ${operation}: ${error?.message || error}`;
|
|
76
|
+
setError(errorMessage);
|
|
77
|
+
debugLog(`Error in ${operation}`, error);
|
|
78
|
+
}, [debugLog]);
|
|
79
|
+
// Load images for a specific page
|
|
80
|
+
const loadPage = useCallback(async (pageNum, isLoadMore = false) => {
|
|
81
|
+
if (!controllerRef.current || !firebaseUidRef.current || !eventIdRef.current) {
|
|
82
|
+
debugLog('Load skipped: missing controller, firebaseUid, or eventId');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Set appropriate loading state
|
|
86
|
+
if (isLoadMore) {
|
|
87
|
+
setIsLoadingMore(true);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
setIsLoading(true);
|
|
91
|
+
}
|
|
92
|
+
setError(null);
|
|
93
|
+
try {
|
|
94
|
+
debugLog(`Loading page ${pageNum}...`, { isLoadMore });
|
|
95
|
+
const response = await controllerRef.current.getImageList(firebaseUidRef.current, eventIdRef.current, pageNum);
|
|
96
|
+
debugLog('Page loaded successfully', {
|
|
97
|
+
page: response.current_page,
|
|
98
|
+
imageCount: response.gallery.length,
|
|
99
|
+
hasNext: response.next_page > 0
|
|
100
|
+
});
|
|
101
|
+
// Update images list
|
|
102
|
+
setImages(prev => {
|
|
103
|
+
if (isLoadMore) {
|
|
104
|
+
// Append new images for load more
|
|
105
|
+
return [...prev, ...response.gallery];
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Replace all images for initial load or refresh
|
|
109
|
+
return response.gallery;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
// Update pagination state
|
|
113
|
+
setCurrentPage(response.current_page);
|
|
114
|
+
setHasMore(response.next_page > 0 && response.gallery.length > 0);
|
|
115
|
+
if (!isInitialized) {
|
|
116
|
+
setIsInitialized(true);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
handleError(`load page ${pageNum}`, err);
|
|
121
|
+
// On error, don't change images if it's load more
|
|
122
|
+
if (!isLoadMore) {
|
|
123
|
+
setImages([]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
if (isLoadMore) {
|
|
128
|
+
setIsLoadingMore(false);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
setIsLoading(false);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}, [debugLog, handleError, isInitialized]);
|
|
135
|
+
// Load more images (next page) - spam-protected
|
|
136
|
+
const loadMore = useCallback(async () => {
|
|
137
|
+
// Prevent multiple concurrent loadMore calls
|
|
138
|
+
if (isLoadMoreRunningRef.current || isLoadingMore || !hasMore) {
|
|
139
|
+
debugLog('Load more skipped', {
|
|
140
|
+
isLoadMoreRunning: isLoadMoreRunningRef.current,
|
|
141
|
+
isLoadingMore,
|
|
142
|
+
hasMore
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Mark as running to prevent spam
|
|
147
|
+
isLoadMoreRunningRef.current = true;
|
|
148
|
+
try {
|
|
149
|
+
debugLog('Loading more images...', { nextPage: currentPage + 1 });
|
|
150
|
+
await loadPage(currentPage + 1, true);
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
// Always reset the running flag
|
|
154
|
+
isLoadMoreRunningRef.current = false;
|
|
155
|
+
}
|
|
156
|
+
}, [isLoadingMore, hasMore, currentPage, loadPage, debugLog]);
|
|
157
|
+
// Refresh from first page
|
|
158
|
+
const refresh = useCallback(async () => {
|
|
159
|
+
debugLog('Refreshing from first page...');
|
|
160
|
+
setCurrentPage(1);
|
|
161
|
+
setHasMore(true);
|
|
162
|
+
await loadPage(1, false);
|
|
163
|
+
}, [loadPage, debugLog]);
|
|
164
|
+
// Reset pagination state
|
|
165
|
+
const reset = useCallback(() => {
|
|
166
|
+
debugLog('Resetting pagination state');
|
|
167
|
+
setImages([]);
|
|
168
|
+
setCurrentPage(1);
|
|
169
|
+
setHasMore(true);
|
|
170
|
+
setError(null);
|
|
171
|
+
setIsInitialized(false);
|
|
172
|
+
// Reset loadMore running flag when page changes
|
|
173
|
+
isLoadMoreRunningRef.current = false;
|
|
174
|
+
}, [debugLog]);
|
|
175
|
+
// Auto-load first page on initialization
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
if (memoizedOptions.autoLoad && controller && firebaseUid && eventId && !isInitialized) {
|
|
178
|
+
debugLog('Auto-loading first page...');
|
|
179
|
+
loadPage(1, false);
|
|
180
|
+
}
|
|
181
|
+
}, [memoizedOptions.autoLoad, controller, firebaseUid, eventId, isInitialized, loadPage, debugLog]);
|
|
182
|
+
// Reset when dependencies change (if autoReset is enabled)
|
|
183
|
+
useEffect(() => {
|
|
184
|
+
if (memoizedOptions.autoReset && isInitialized) {
|
|
185
|
+
debugLog('Dependencies changed, resetting state');
|
|
186
|
+
reset();
|
|
187
|
+
}
|
|
188
|
+
}, [controller, firebaseUid, eventId, memoizedOptions.autoReset, isInitialized, reset, debugLog]);
|
|
189
|
+
// Paging info object - memoized to prevent re-renders
|
|
190
|
+
const info = useMemo(() => ({
|
|
191
|
+
isLoading,
|
|
192
|
+
isLoadingMore,
|
|
193
|
+
error,
|
|
194
|
+
currentPage,
|
|
195
|
+
hasMore,
|
|
196
|
+
totalImages: images.length,
|
|
197
|
+
isInitialized
|
|
198
|
+
}), [isLoading, isLoadingMore, error, currentPage, hasMore, images.length, isInitialized]);
|
|
199
|
+
// Actions object - memoized to prevent re-renders
|
|
200
|
+
const actions = useMemo(() => ({
|
|
201
|
+
loadMore,
|
|
202
|
+
refresh,
|
|
203
|
+
reset
|
|
204
|
+
}), [loadMore, refresh, reset]);
|
|
205
|
+
// Return object - memoized to prevent re-renders
|
|
206
|
+
return useMemo(() => ({
|
|
207
|
+
images,
|
|
208
|
+
info,
|
|
209
|
+
actions
|
|
210
|
+
}), [images, info, actions]);
|
|
211
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export { useEditorHeadless } from './lib/hooks/useEditorHeadless';
|
|
|
29
29
|
export { useAdjustmentHistory, type UseAdjustmentHistoryReturn, type HistoryInfo, type HistoryActions, type HistoryConfig } from './hooks/useAdjustmentHistory';
|
|
30
30
|
export { useAdjustmentHistoryBatch, type UseAdjustmentHistoryBatchReturn, type BatchAdjustmentState, type ImageAdjustmentConfig, type BatchHistoryInfo, type BatchHistoryActions, type BatchHistoryConfig } from './hooks/useAdjustmentHistoryBatch';
|
|
31
31
|
export { usePreset, type UsePresetReturn, type PresetInfo, type PresetActions, type PresetOptions } from './hooks/usePreset';
|
|
32
|
+
export { usePaging, type UsePagingReturn, type PagingInfo, type PagingActions, type PagingOptions } from './hooks/usePaging';
|
|
32
33
|
export { default as useColors } from './themes/colors';
|
|
33
34
|
export { default as useHonchoTypography } from './themes/honchoTheme';
|
|
34
35
|
export { default as useIsMobile } from './utils/isMobile';
|
package/dist/index.js
CHANGED
|
@@ -28,6 +28,8 @@ export { useAdjustmentHistory } from './hooks/useAdjustmentHistory';
|
|
|
28
28
|
export { useAdjustmentHistoryBatch } from './hooks/useAdjustmentHistoryBatch';
|
|
29
29
|
// --- Preset Hook ---
|
|
30
30
|
export { usePreset } from './hooks/usePreset';
|
|
31
|
+
// --- Paging Hook ---
|
|
32
|
+
export { usePaging } from './hooks/usePaging';
|
|
31
33
|
// --- Theme & Utils ---
|
|
32
34
|
export { default as useColors } from './themes/colors';
|
|
33
35
|
export { default as useHonchoTypography } from './themes/honchoTheme';
|