@yogiswara/honcho-editor-ui 2.5.10 → 2.6.0
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/components/editor/HBulkPreset.js +12 -2
- package/dist/hooks/demo/HonchoEditorBulkDemo.d.ts +3 -0
- package/dist/hooks/demo/HonchoEditorBulkDemo.js +228 -0
- package/dist/hooks/demo/HonchoEditorSingleCleanDemo.d.ts +3 -0
- package/dist/hooks/demo/HonchoEditorSingleCleanDemo.js +354 -0
- package/dist/hooks/demo/index.d.ts +2 -0
- package/dist/hooks/demo/index.js +2 -0
- package/dist/hooks/editor/type.d.ts +71 -0
- package/dist/hooks/editor/useHonchoEditorBulk.d.ts +10 -12
- package/dist/hooks/editor/useHonchoEditorBulk.js +126 -10
- package/dist/hooks/editor/useHonchoEditorSingle.d.ts +43 -0
- package/dist/hooks/editor/useHonchoEditorSingle.js +158 -0
- package/dist/hooks/useAdjustmentHistory.d.ts +9 -5
- package/dist/hooks/useAdjustmentHistory.js +187 -31
- package/dist/hooks/useAdjustmentHistoryBatch.d.ts +18 -1
- package/dist/hooks/useAdjustmentHistoryBatch.js +627 -201
- package/dist/hooks/useGallerySwipe.d.ts +1 -1
- package/dist/hooks/usePaging.d.ts +1 -1
- package/dist/hooks/usePaging.js +1 -1
- package/dist/hooks/usePreset.d.ts +1 -1
- package/dist/hooks/usePreset.js +35 -35
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/lib/context/EditorContext.d.ts +10 -0
- package/dist/lib/context/EditorContext.js +4 -2
- package/dist/lib/hooks/useEditorHeadless.d.ts +18 -2
- package/dist/lib/hooks/useEditorHeadless.js +142 -63
- package/dist/utils/adjustment.d.ts +2 -1
- package/dist/utils/adjustment.js +16 -0
- package/dist/utils/imageLoader.d.ts +11 -0
- package/dist/utils/imageLoader.js +53 -0
- package/package.json +1 -1
- package/dist/components/editor/GalleryAlbum/SimplifiedAlbumGallery.d.ts +0 -17
- package/dist/components/editor/GalleryAlbum/SimplifiedAlbumGallery.js +0 -14
- package/dist/components/editor/GalleryAlbum/SimplifiedImageItem.d.ts +0 -8
- package/dist/components/editor/GalleryAlbum/SimplifiedImageItem.js +0 -30
- package/dist/components/editor/HImageEditorPage.d.ts +0 -1
- package/dist/components/editor/HImageEditorPage.js +0 -187
- package/dist/hooks/__tests__/useGallerySwipe.test.d.ts +0 -0
- package/dist/hooks/__tests__/useGallerySwipe.test.js +0 -619
- package/dist/hooks/editor/useHonchoEditor.d.ts +0 -203
- package/dist/hooks/editor/useHonchoEditor.js +0 -716
- package/dist/hooks/useAdjustmentHistory.demo.d.ts +0 -8
- package/dist/hooks/useAdjustmentHistory.demo.js +0 -106
- package/dist/hooks/useAdjustmentHistory.example.d.ts +0 -38
- package/dist/hooks/useAdjustmentHistory.example.js +0 -182
- package/dist/hooks/useAdjustmentHistory.syncDemo.d.ts +0 -8
- package/dist/hooks/useAdjustmentHistory.syncDemo.js +0 -180
- package/dist/hooks/useGallerySwipe.example.d.ts +0 -24
- package/dist/hooks/useGallerySwipe.example.js +0 -184
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Demo component showing batch mode behavior
|
|
3
|
-
*/
|
|
4
|
-
export declare function BatchModeDemo(): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
/**
|
|
6
|
-
* Example showing smooth preset application
|
|
7
|
-
*/
|
|
8
|
-
export declare function SmoothPresetDemo(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState } from 'react';
|
|
3
|
-
import { useAdjustmentHistory } from './useAdjustmentHistory';
|
|
4
|
-
const initialAdjustments = {
|
|
5
|
-
tempScore: 0, tintScore: 0, vibranceScore: 0, saturationScore: 0,
|
|
6
|
-
exposureScore: 0, highlightsScore: 0, shadowsScore: 0, whitesScore: 0,
|
|
7
|
-
blacksScore: 0, contrastScore: 0, clarityScore: 0, sharpnessScore: 0,
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Demo component showing batch mode behavior
|
|
11
|
-
*/
|
|
12
|
-
export function BatchModeDemo() {
|
|
13
|
-
const { currentState, historyInfo, actions, config } = useAdjustmentHistory(initialAdjustments);
|
|
14
|
-
const [updateCount, setUpdateCount] = useState(0);
|
|
15
|
-
// Track UI updates
|
|
16
|
-
React.useEffect(() => {
|
|
17
|
-
setUpdateCount(prev => prev + 1);
|
|
18
|
-
}, [currentState]);
|
|
19
|
-
const handleBatchUpdates = async () => {
|
|
20
|
-
setUpdateCount(0); // Reset counter
|
|
21
|
-
console.log('Starting batch mode...');
|
|
22
|
-
config.setBatchMode(true);
|
|
23
|
-
// These will update currentState 4 times (UI updates)
|
|
24
|
-
console.log('Push state 1...');
|
|
25
|
-
actions.pushState({ ...currentState, tempScore: 25 });
|
|
26
|
-
console.log('Push state 2...');
|
|
27
|
-
actions.pushState({ ...currentState, tempScore: 50 });
|
|
28
|
-
console.log('Push state 3...');
|
|
29
|
-
actions.pushState({ ...currentState, tempScore: 75 });
|
|
30
|
-
console.log('Push state 4...');
|
|
31
|
-
actions.pushState({ ...currentState, tempScore: 100 });
|
|
32
|
-
console.log('Ending batch mode...');
|
|
33
|
-
config.setBatchMode(false); // Only now will 1 history entry be created
|
|
34
|
-
console.log('Batch complete!');
|
|
35
|
-
};
|
|
36
|
-
const handleInstantUpdates = () => {
|
|
37
|
-
setUpdateCount(0); // Reset counter
|
|
38
|
-
// These will create 4 history entries (normal mode)
|
|
39
|
-
actions.pushState({ ...currentState, tintScore: 25 });
|
|
40
|
-
actions.pushState({ ...currentState, tintScore: 50 });
|
|
41
|
-
actions.pushState({ ...currentState, tintScore: 75 });
|
|
42
|
-
actions.pushState({ ...currentState, tintScore: 100 });
|
|
43
|
-
};
|
|
44
|
-
return (_jsxs("div", { style: { padding: '20px', fontFamily: 'monospace' }, children: [_jsx("h2", { children: "Batch Mode Demo" }), _jsxs("div", { style: { marginBottom: '20px', padding: '10px', backgroundColor: '#f5f5f5' }, children: [_jsx("strong", { children: "Current State:" }), _jsxs("div", { children: ["Temperature: ", currentState.tempScore] }), _jsxs("div", { children: ["Tint: ", currentState.tintScore] }), _jsxs("div", { children: ["UI Updates: ", updateCount] }), _jsxs("div", { children: ["History Size: ", historyInfo.totalStates] }), _jsxs("div", { children: ["Can Undo: ", historyInfo.canUndo ? 'Yes' : 'No'] }), _jsxs("div", { children: ["Batch Mode: ", historyInfo.isBatchMode ? 'Active' : 'Inactive'] })] }), _jsxs("div", { style: { display: 'flex', gap: '10px', marginBottom: '20px' }, children: [_jsx("button", { onClick: handleBatchUpdates, style: { padding: '10px', backgroundColor: '#4CAF50', color: 'white', border: 'none' }, children: "Batch Mode (4 UI updates, 1 history entry)" }), _jsx("button", { onClick: handleInstantUpdates, style: { padding: '10px', backgroundColor: '#2196F3', color: 'white', border: 'none' }, children: "Normal Mode (4 UI updates, 4 history entries)" })] }), _jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [_jsx("button", { onClick: actions.undo, disabled: !historyInfo.canUndo, style: {
|
|
45
|
-
padding: '10px',
|
|
46
|
-
backgroundColor: historyInfo.canUndo ? '#FF9800' : '#ccc',
|
|
47
|
-
color: 'white',
|
|
48
|
-
border: 'none'
|
|
49
|
-
}, children: "Undo" }), _jsx("button", { onClick: actions.redo, disabled: !historyInfo.canRedo, style: {
|
|
50
|
-
padding: '10px',
|
|
51
|
-
backgroundColor: historyInfo.canRedo ? '#9C27B0' : '#ccc',
|
|
52
|
-
color: 'white',
|
|
53
|
-
border: 'none'
|
|
54
|
-
}, children: "Redo" }), _jsx("button", { onClick: () => actions.reset(initialAdjustments), style: { padding: '10px', backgroundColor: '#f44336', color: 'white', border: 'none' }, children: "Reset" })] }), _jsxs("div", { style: { marginTop: '20px', fontSize: '12px', color: '#666' }, children: [_jsx("h3", { children: "How it works:" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Batch Mode:" }), " UI updates immediately on each pushState, but only final state is saved to history when batch ends"] }), _jsxs("li", { children: [_jsx("strong", { children: "Normal Mode:" }), " Each pushState creates both UI update and history entry"] }), _jsxs("li", { children: [_jsx("strong", { children: "Result:" }), " Smooth UI animations with clean undo/redo history"] })] })] })] }));
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Example showing smooth preset application
|
|
58
|
-
*/
|
|
59
|
-
export function SmoothPresetDemo() {
|
|
60
|
-
const { currentState, historyInfo, actions, config } = useAdjustmentHistory(initialAdjustments);
|
|
61
|
-
const dramaticPreset = {
|
|
62
|
-
tempScore: 50, tintScore: -20, vibranceScore: 80, saturationScore: 60,
|
|
63
|
-
exposureScore: 30, highlightsScore: -40, shadowsScore: 40, whitesScore: 20,
|
|
64
|
-
blacksScore: -30, contrastScore: 70, clarityScore: 50, sharpnessScore: 40,
|
|
65
|
-
};
|
|
66
|
-
const handleSmoothPreset = async () => {
|
|
67
|
-
config.setBatchMode(true);
|
|
68
|
-
// Create smooth transition with multiple steps
|
|
69
|
-
const steps = 8;
|
|
70
|
-
for (let i = 1; i <= steps; i++) {
|
|
71
|
-
const progress = i / steps;
|
|
72
|
-
const intermediateState = {
|
|
73
|
-
tempScore: Math.round(currentState.tempScore + (dramaticPreset.tempScore - currentState.tempScore) * progress),
|
|
74
|
-
tintScore: Math.round(currentState.tintScore + (dramaticPreset.tintScore - currentState.tintScore) * progress),
|
|
75
|
-
vibranceScore: Math.round(currentState.vibranceScore + (dramaticPreset.vibranceScore - currentState.vibranceScore) * progress),
|
|
76
|
-
saturationScore: Math.round(currentState.saturationScore + (dramaticPreset.saturationScore - currentState.saturationScore) * progress),
|
|
77
|
-
exposureScore: Math.round(currentState.exposureScore + (dramaticPreset.exposureScore - currentState.exposureScore) * progress),
|
|
78
|
-
highlightsScore: Math.round(currentState.highlightsScore + (dramaticPreset.highlightsScore - currentState.highlightsScore) * progress),
|
|
79
|
-
shadowsScore: Math.round(currentState.shadowsScore + (dramaticPreset.shadowsScore - currentState.shadowsScore) * progress),
|
|
80
|
-
whitesScore: Math.round(currentState.whitesScore + (dramaticPreset.whitesScore - currentState.whitesScore) * progress),
|
|
81
|
-
blacksScore: Math.round(currentState.blacksScore + (dramaticPreset.blacksScore - currentState.blacksScore) * progress),
|
|
82
|
-
contrastScore: Math.round(currentState.contrastScore + (dramaticPreset.contrastScore - currentState.contrastScore) * progress),
|
|
83
|
-
clarityScore: Math.round(currentState.clarityScore + (dramaticPreset.clarityScore - currentState.clarityScore) * progress),
|
|
84
|
-
sharpnessScore: Math.round(currentState.sharpnessScore + (dramaticPreset.sharpnessScore - currentState.sharpnessScore) * progress),
|
|
85
|
-
};
|
|
86
|
-
actions.pushState(intermediateState);
|
|
87
|
-
// Small delay for smooth animation
|
|
88
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
89
|
-
}
|
|
90
|
-
config.setBatchMode(false); // Commit final state
|
|
91
|
-
};
|
|
92
|
-
return (_jsxs("div", { style: { padding: '20px', fontFamily: 'monospace' }, children: [_jsx("h2", { children: "Smooth Preset Application" }), _jsxs("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px', marginBottom: '20px', fontSize: '12px' }, children: [_jsxs("div", { children: ["Temp: ", currentState.tempScore] }), _jsxs("div", { children: ["Tint: ", currentState.tintScore] }), _jsxs("div", { children: ["Vibrance: ", currentState.vibranceScore] }), _jsxs("div", { children: ["Saturation: ", currentState.saturationScore] }), _jsxs("div", { children: ["Exposure: ", currentState.exposureScore] }), _jsxs("div", { children: ["Highlights: ", currentState.highlightsScore] }), _jsxs("div", { children: ["Shadows: ", currentState.shadowsScore] }), _jsxs("div", { children: ["Whites: ", currentState.whitesScore] }), _jsxs("div", { children: ["Blacks: ", currentState.blacksScore] }), _jsxs("div", { children: ["Contrast: ", currentState.contrastScore] }), _jsxs("div", { children: ["Clarity: ", currentState.clarityScore] }), _jsxs("div", { children: ["Sharpness: ", currentState.sharpnessScore] })] }), _jsx("button", { onClick: handleSmoothPreset, style: {
|
|
93
|
-
padding: '15px 30px',
|
|
94
|
-
backgroundColor: '#4CAF50',
|
|
95
|
-
color: 'white',
|
|
96
|
-
border: 'none',
|
|
97
|
-
fontSize: '16px',
|
|
98
|
-
marginRight: '10px'
|
|
99
|
-
}, children: "Apply Dramatic Preset (Smooth)" }), _jsx("button", { onClick: actions.undo, disabled: !historyInfo.canUndo, style: {
|
|
100
|
-
padding: '15px 30px',
|
|
101
|
-
backgroundColor: historyInfo.canUndo ? '#FF9800' : '#ccc',
|
|
102
|
-
color: 'white',
|
|
103
|
-
border: 'none',
|
|
104
|
-
fontSize: '16px'
|
|
105
|
-
}, children: "Undo Preset" }), _jsx("div", { style: { marginTop: '20px', fontSize: '12px', color: '#666' }, children: _jsx("p", { children: "This demo shows smooth preset application with 8 intermediate steps, but only 1 undo operation!" }) })] }));
|
|
106
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { type HistoryInfo } from './useAdjustmentHistory';
|
|
2
|
-
import { AdjustmentState } from './editor/useHonchoEditor';
|
|
3
|
-
export declare function useEditorWithHistory(): {
|
|
4
|
-
adjustments: AdjustmentState;
|
|
5
|
-
canUndo: boolean;
|
|
6
|
-
canRedo: boolean;
|
|
7
|
-
undo: () => void;
|
|
8
|
-
redo: () => void;
|
|
9
|
-
updateTemperature: (newTemp: number) => void;
|
|
10
|
-
applyPresetWithSmoothUI: (presetState: AdjustmentState) => void;
|
|
11
|
-
updateMultipleAdjustments: (updates: Partial<AdjustmentState>) => void;
|
|
12
|
-
loadSavedHistory: (savedStates: AdjustmentState[]) => void;
|
|
13
|
-
loadHistoryToSpecificPoint: (savedStates: AdjustmentState[], targetIndex: number) => void;
|
|
14
|
-
mergeWithNewStates: (newStates: AdjustmentState[]) => void;
|
|
15
|
-
loadPresetVariations: () => void;
|
|
16
|
-
resetAdjustments: () => void;
|
|
17
|
-
jumpToIndex: (index: number) => void;
|
|
18
|
-
getHistory: () => AdjustmentState[];
|
|
19
|
-
clearHistory: () => void;
|
|
20
|
-
syncHistory: (newHistory: AdjustmentState[], targetIndex?: number) => void;
|
|
21
|
-
setBatchMode: (enabled: boolean) => void;
|
|
22
|
-
setMaxSize: (size: number | "unlimited") => void;
|
|
23
|
-
getMemoryUsage: () => number;
|
|
24
|
-
historyInfo: HistoryInfo;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Example integration with your existing useHonchoEditor pattern
|
|
28
|
-
*/
|
|
29
|
-
export declare function integrateWithHonchoEditor(): {
|
|
30
|
-
currentAdjustments: AdjustmentState;
|
|
31
|
-
canUndo: boolean;
|
|
32
|
-
canRedo: boolean;
|
|
33
|
-
handleSliderChange: (key: keyof AdjustmentState, value: number) => void;
|
|
34
|
-
handlePresetWithAnimation: (presetState: AdjustmentState) => Promise<void>;
|
|
35
|
-
handleUndo: () => void;
|
|
36
|
-
handleRedo: () => void;
|
|
37
|
-
handleRevert: () => void;
|
|
38
|
-
};
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { useAdjustmentHistory } from './useAdjustmentHistory';
|
|
2
|
-
/**
|
|
3
|
-
* Example usage of the simplified useAdjustmentHistory hook
|
|
4
|
-
* This shows how to integrate it with your existing useHonchoEditor
|
|
5
|
-
*/
|
|
6
|
-
// Example initial adjustment state
|
|
7
|
-
const initialAdjustments = {
|
|
8
|
-
tempScore: 0,
|
|
9
|
-
tintScore: 0,
|
|
10
|
-
vibranceScore: 0,
|
|
11
|
-
saturationScore: 0,
|
|
12
|
-
exposureScore: 0,
|
|
13
|
-
highlightsScore: 0,
|
|
14
|
-
shadowsScore: 0,
|
|
15
|
-
whitesScore: 0,
|
|
16
|
-
blacksScore: 0,
|
|
17
|
-
contrastScore: 0,
|
|
18
|
-
clarityScore: 0,
|
|
19
|
-
sharpnessScore: 0,
|
|
20
|
-
};
|
|
21
|
-
export function useEditorWithHistory() {
|
|
22
|
-
// Initialize the adjustment history hook
|
|
23
|
-
const { currentState: currentAdjustments, historyInfo, actions, config } = useAdjustmentHistory(initialAdjustments, {
|
|
24
|
-
maxSize: 100, // Keep last 100 states
|
|
25
|
-
enableBatching: false, // Start with batching disabled
|
|
26
|
-
devWarnings: true // Show performance warnings in development
|
|
27
|
-
});
|
|
28
|
-
// Example: Update a single adjustment value
|
|
29
|
-
const updateTemperature = (newTemp) => {
|
|
30
|
-
const newState = {
|
|
31
|
-
...currentAdjustments,
|
|
32
|
-
tempScore: newTemp
|
|
33
|
-
};
|
|
34
|
-
actions.pushState(newState);
|
|
35
|
-
};
|
|
36
|
-
// Example: Apply preset with batch mode for smooth UI updates
|
|
37
|
-
const applyPresetWithSmoothUI = (presetState) => {
|
|
38
|
-
// Enable batch mode to group all changes into one undo operation
|
|
39
|
-
config.setBatchMode(true);
|
|
40
|
-
// These will update the UI immediately but not create history entries
|
|
41
|
-
actions.pushState({ ...currentAdjustments, tempScore: presetState.tempScore });
|
|
42
|
-
actions.pushState({ ...currentAdjustments, tempScore: presetState.tempScore, tintScore: presetState.tintScore });
|
|
43
|
-
actions.pushState({ ...currentAdjustments, tempScore: presetState.tempScore, tintScore: presetState.tintScore, exposureScore: presetState.exposureScore });
|
|
44
|
-
actions.pushState(presetState); // Final complete state
|
|
45
|
-
// Disable batch mode to commit only the final state to history
|
|
46
|
-
config.setBatchMode(false);
|
|
47
|
-
// Result: UI updated 4 times (smooth animation), but only 1 undo operation
|
|
48
|
-
};
|
|
49
|
-
// Example: Bulk update multiple adjustments
|
|
50
|
-
const updateMultipleAdjustments = (updates) => {
|
|
51
|
-
config.setBatchMode(true); // Start batching
|
|
52
|
-
const newState = {
|
|
53
|
-
...currentAdjustments,
|
|
54
|
-
...updates
|
|
55
|
-
};
|
|
56
|
-
actions.pushState(newState);
|
|
57
|
-
config.setBatchMode(false); // Commit batch
|
|
58
|
-
};
|
|
59
|
-
// Example: Load saved history from storage or API
|
|
60
|
-
const loadSavedHistory = (savedStates) => {
|
|
61
|
-
// Load complete history and set to last state
|
|
62
|
-
actions.syncHistory(savedStates);
|
|
63
|
-
};
|
|
64
|
-
// Example: Load history and jump to specific point
|
|
65
|
-
const loadHistoryToSpecificPoint = (savedStates, targetIndex) => {
|
|
66
|
-
// Load history and set current position to specific index
|
|
67
|
-
actions.syncHistory(savedStates, targetIndex);
|
|
68
|
-
};
|
|
69
|
-
// Example: Merge current history with new states
|
|
70
|
-
const mergeWithNewStates = (newStates) => {
|
|
71
|
-
const currentHistory = actions.getHistory();
|
|
72
|
-
const mergedHistory = [...currentHistory, ...newStates];
|
|
73
|
-
actions.syncHistory(mergedHistory);
|
|
74
|
-
};
|
|
75
|
-
// Example: Replace with preset variations
|
|
76
|
-
const loadPresetVariations = () => {
|
|
77
|
-
const variations = [
|
|
78
|
-
initialAdjustments, // Original
|
|
79
|
-
{ ...initialAdjustments, tempScore: 25 }, // Warm
|
|
80
|
-
{ ...initialAdjustments, tempScore: -25 }, // Cool
|
|
81
|
-
{ ...initialAdjustments, exposureScore: 20 }, // Bright
|
|
82
|
-
{ ...initialAdjustments, exposureScore: -20 }, // Dark
|
|
83
|
-
];
|
|
84
|
-
actions.syncHistory(variations, 0); // Load variations, start at original
|
|
85
|
-
};
|
|
86
|
-
// Example: Reset to initial state
|
|
87
|
-
const resetAdjustments = () => {
|
|
88
|
-
actions.reset(initialAdjustments);
|
|
89
|
-
};
|
|
90
|
-
return {
|
|
91
|
-
// Current adjustment values
|
|
92
|
-
adjustments: currentAdjustments,
|
|
93
|
-
// History controls
|
|
94
|
-
canUndo: historyInfo.canUndo,
|
|
95
|
-
canRedo: historyInfo.canRedo,
|
|
96
|
-
undo: actions.undo,
|
|
97
|
-
redo: actions.redo,
|
|
98
|
-
// Adjustment functions
|
|
99
|
-
updateTemperature,
|
|
100
|
-
applyPresetWithSmoothUI,
|
|
101
|
-
updateMultipleAdjustments,
|
|
102
|
-
loadSavedHistory,
|
|
103
|
-
loadHistoryToSpecificPoint,
|
|
104
|
-
mergeWithNewStates,
|
|
105
|
-
loadPresetVariations,
|
|
106
|
-
resetAdjustments,
|
|
107
|
-
// Advanced features
|
|
108
|
-
jumpToIndex: actions.jumpToIndex,
|
|
109
|
-
getHistory: actions.getHistory,
|
|
110
|
-
clearHistory: actions.clearHistory,
|
|
111
|
-
syncHistory: actions.syncHistory,
|
|
112
|
-
// Configuration
|
|
113
|
-
setBatchMode: config.setBatchMode,
|
|
114
|
-
setMaxSize: config.setMaxSize,
|
|
115
|
-
getMemoryUsage: config.getMemoryUsage,
|
|
116
|
-
// History info
|
|
117
|
-
historyInfo
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Example integration with your existing useHonchoEditor pattern
|
|
122
|
-
*/
|
|
123
|
-
export function integrateWithHonchoEditor() {
|
|
124
|
-
const history = useAdjustmentHistory(initialAdjustments);
|
|
125
|
-
// Replace your current manual history management with this:
|
|
126
|
-
// Instead of:
|
|
127
|
-
// const [history, setHistory] = useState<AdjustmentState[]>([initialAdjustments]);
|
|
128
|
-
// const [historyIndex, setHistoryIndex] = useState(0);
|
|
129
|
-
// Use:
|
|
130
|
-
const currentAdjustments = history.currentState;
|
|
131
|
-
const canUndo = history.historyInfo.canUndo;
|
|
132
|
-
const canRedo = history.historyInfo.canRedo;
|
|
133
|
-
// When any adjustment changes (e.g., slider value):
|
|
134
|
-
const handleSliderChange = (key, value) => {
|
|
135
|
-
const newState = {
|
|
136
|
-
...currentAdjustments,
|
|
137
|
-
[key]: value
|
|
138
|
-
};
|
|
139
|
-
history.actions.pushState(newState);
|
|
140
|
-
};
|
|
141
|
-
// Smooth preset application with multiple UI updates
|
|
142
|
-
const handlePresetWithAnimation = async (presetState) => {
|
|
143
|
-
history.config.setBatchMode(true);
|
|
144
|
-
// Animate through intermediate states for smooth UI
|
|
145
|
-
const steps = 4;
|
|
146
|
-
for (let i = 1; i <= steps; i++) {
|
|
147
|
-
const progress = i / steps;
|
|
148
|
-
const intermediateState = {
|
|
149
|
-
tempScore: Math.round(currentAdjustments.tempScore + (presetState.tempScore - currentAdjustments.tempScore) * progress),
|
|
150
|
-
tintScore: Math.round(currentAdjustments.tintScore + (presetState.tintScore - currentAdjustments.tintScore) * progress),
|
|
151
|
-
vibranceScore: Math.round(currentAdjustments.vibranceScore + (presetState.vibranceScore - currentAdjustments.vibranceScore) * progress),
|
|
152
|
-
saturationScore: Math.round(currentAdjustments.saturationScore + (presetState.saturationScore - currentAdjustments.saturationScore) * progress),
|
|
153
|
-
exposureScore: Math.round(currentAdjustments.exposureScore + (presetState.exposureScore - currentAdjustments.exposureScore) * progress),
|
|
154
|
-
highlightsScore: Math.round(currentAdjustments.highlightsScore + (presetState.highlightsScore - currentAdjustments.highlightsScore) * progress),
|
|
155
|
-
shadowsScore: Math.round(currentAdjustments.shadowsScore + (presetState.shadowsScore - currentAdjustments.shadowsScore) * progress),
|
|
156
|
-
whitesScore: Math.round(currentAdjustments.whitesScore + (presetState.whitesScore - currentAdjustments.whitesScore) * progress),
|
|
157
|
-
blacksScore: Math.round(currentAdjustments.blacksScore + (presetState.blacksScore - currentAdjustments.blacksScore) * progress),
|
|
158
|
-
contrastScore: Math.round(currentAdjustments.contrastScore + (presetState.contrastScore - currentAdjustments.contrastScore) * progress),
|
|
159
|
-
clarityScore: Math.round(currentAdjustments.clarityScore + (presetState.clarityScore - currentAdjustments.clarityScore) * progress),
|
|
160
|
-
sharpnessScore: Math.round(currentAdjustments.sharpnessScore + (presetState.sharpnessScore - currentAdjustments.sharpnessScore) * progress),
|
|
161
|
-
};
|
|
162
|
-
history.actions.pushState(intermediateState);
|
|
163
|
-
// Small delay for smooth animation
|
|
164
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
165
|
-
}
|
|
166
|
-
history.config.setBatchMode(false); // Commit only final state to history
|
|
167
|
-
};
|
|
168
|
-
// Your existing undo/redo handlers become:
|
|
169
|
-
const handleUndo = history.actions.undo;
|
|
170
|
-
const handleRedo = history.actions.redo;
|
|
171
|
-
const handleRevert = () => history.actions.reset(initialAdjustments);
|
|
172
|
-
return {
|
|
173
|
-
currentAdjustments,
|
|
174
|
-
canUndo,
|
|
175
|
-
canRedo,
|
|
176
|
-
handleSliderChange,
|
|
177
|
-
handlePresetWithAnimation,
|
|
178
|
-
handleUndo,
|
|
179
|
-
handleRedo,
|
|
180
|
-
handleRevert
|
|
181
|
-
};
|
|
182
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Demo component showing syncHistory functionality
|
|
3
|
-
*/
|
|
4
|
-
export declare function SyncHistoryDemo(): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
/**
|
|
6
|
-
* Real-world integration example
|
|
7
|
-
*/
|
|
8
|
-
export declare function RealWorldSyncExample(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { useAdjustmentHistory } from './useAdjustmentHistory';
|
|
4
|
-
const initialAdjustments = {
|
|
5
|
-
tempScore: 0, tintScore: 0, vibranceScore: 0, saturationScore: 0,
|
|
6
|
-
exposureScore: 0, highlightsScore: 0, shadowsScore: 0, whitesScore: 0,
|
|
7
|
-
blacksScore: 0, contrastScore: 0, clarityScore: 0, sharpnessScore: 0,
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Demo component showing syncHistory functionality
|
|
11
|
-
*/
|
|
12
|
-
export function SyncHistoryDemo() {
|
|
13
|
-
const { currentState, historyInfo, actions, config } = useAdjustmentHistory(initialAdjustments);
|
|
14
|
-
// Sample history data for demo
|
|
15
|
-
const [savedHistoryData] = useState([
|
|
16
|
-
{ ...initialAdjustments }, // Original
|
|
17
|
-
{ ...initialAdjustments, tempScore: 25, tintScore: 10 }, // Warm
|
|
18
|
-
{ ...initialAdjustments, tempScore: 50, tintScore: 20, exposureScore: 15 }, // Warmer + Bright
|
|
19
|
-
{ ...initialAdjustments, tempScore: 75, tintScore: 30, exposureScore: 30, contrastScore: 20 }, // Dramatic warm
|
|
20
|
-
{ ...initialAdjustments, tempScore: 100, tintScore: 40, exposureScore: 50, contrastScore: 40, clarityScore: 25 }, // Final look
|
|
21
|
-
]);
|
|
22
|
-
const [presetCollections] = useState({
|
|
23
|
-
vintage: [
|
|
24
|
-
{ ...initialAdjustments },
|
|
25
|
-
{ ...initialAdjustments, tempScore: 30, exposureScore: -10 },
|
|
26
|
-
{ ...initialAdjustments, tempScore: 30, exposureScore: -10, contrastScore: -15 },
|
|
27
|
-
{ ...initialAdjustments, tempScore: 30, exposureScore: -10, contrastScore: -15, saturationScore: -20 },
|
|
28
|
-
{ ...initialAdjustments, tempScore: 30, exposureScore: -10, contrastScore: -15, saturationScore: -20, clarityScore: -10 },
|
|
29
|
-
],
|
|
30
|
-
dramatic: [
|
|
31
|
-
{ ...initialAdjustments },
|
|
32
|
-
{ ...initialAdjustments, contrastScore: 30 },
|
|
33
|
-
{ ...initialAdjustments, contrastScore: 30, clarityScore: 40 },
|
|
34
|
-
{ ...initialAdjustments, contrastScore: 30, clarityScore: 40, shadowsScore: -20 },
|
|
35
|
-
{ ...initialAdjustments, contrastScore: 30, clarityScore: 40, shadowsScore: -20, highlightsScore: -10 },
|
|
36
|
-
],
|
|
37
|
-
cool: [
|
|
38
|
-
{ ...initialAdjustments },
|
|
39
|
-
{ ...initialAdjustments, tempScore: -25 },
|
|
40
|
-
{ ...initialAdjustments, tempScore: -25, tintScore: 15 },
|
|
41
|
-
{ ...initialAdjustments, tempScore: -25, tintScore: 15, vibranceScore: 20 },
|
|
42
|
-
{ ...initialAdjustments, tempScore: -25, tintScore: 15, vibranceScore: 20, saturationScore: 10 },
|
|
43
|
-
]
|
|
44
|
-
});
|
|
45
|
-
// Load saved editing session
|
|
46
|
-
const handleLoadSavedSession = () => {
|
|
47
|
-
actions.syncHistory(savedHistoryData);
|
|
48
|
-
console.log('Loaded saved editing session with', savedHistoryData.length, 'states');
|
|
49
|
-
};
|
|
50
|
-
// Load saved session to specific point
|
|
51
|
-
const handleLoadToSpecificPoint = (index) => {
|
|
52
|
-
actions.syncHistory(savedHistoryData, index);
|
|
53
|
-
console.log('Loaded saved session to step', index + 1);
|
|
54
|
-
};
|
|
55
|
-
// Load preset collection
|
|
56
|
-
const handleLoadPresetCollection = (collectionName) => {
|
|
57
|
-
const collection = presetCollections[collectionName];
|
|
58
|
-
if (collection) {
|
|
59
|
-
actions.syncHistory(collection, 0); // Start at original
|
|
60
|
-
console.log('Loaded', collectionName, 'preset collection');
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
// Simulate loading from API/localStorage
|
|
64
|
-
const handleLoadFromStorage = () => {
|
|
65
|
-
// Simulate API call or localStorage read
|
|
66
|
-
const mockStoredData = [
|
|
67
|
-
{ ...initialAdjustments, tempScore: 15, exposureScore: 10 },
|
|
68
|
-
{ ...initialAdjustments, tempScore: 15, exposureScore: 10, contrastScore: 20 },
|
|
69
|
-
{ ...initialAdjustments, tempScore: 15, exposureScore: 10, contrastScore: 20, clarityScore: 15 },
|
|
70
|
-
];
|
|
71
|
-
actions.syncHistory(mockStoredData, 2); // Load to last state
|
|
72
|
-
console.log('Loaded from storage:', mockStoredData.length, 'states');
|
|
73
|
-
};
|
|
74
|
-
// Export current history
|
|
75
|
-
const handleExportHistory = () => {
|
|
76
|
-
const currentHistory = actions.getHistory();
|
|
77
|
-
console.log('Current history to export:', currentHistory);
|
|
78
|
-
// In real app, you might:
|
|
79
|
-
// localStorage.setItem('adjustmentHistory', JSON.stringify(currentHistory));
|
|
80
|
-
// or send to API
|
|
81
|
-
alert(`Exported ${currentHistory.length} states to console (check browser dev tools)`);
|
|
82
|
-
};
|
|
83
|
-
// Merge with additional states
|
|
84
|
-
const handleMergeStates = () => {
|
|
85
|
-
const currentHistory = actions.getHistory();
|
|
86
|
-
const additionalStates = [
|
|
87
|
-
{ ...currentState, sharpnessScore: 25 },
|
|
88
|
-
{ ...currentState, sharpnessScore: 25, clarityScore: currentState.clarityScore + 15 },
|
|
89
|
-
];
|
|
90
|
-
const mergedHistory = [...currentHistory, ...additionalStates];
|
|
91
|
-
actions.syncHistory(mergedHistory);
|
|
92
|
-
console.log('Merged additional states, total:', mergedHistory.length);
|
|
93
|
-
};
|
|
94
|
-
return (_jsxs("div", { style: { padding: '20px', fontFamily: 'monospace' }, children: [_jsx("h2", { children: "syncHistory Demo" }), _jsxs("div", { style: { marginBottom: '20px', padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '5px' }, children: [_jsx("h3", { children: "Current State" }), _jsxs("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px', fontSize: '12px' }, children: [_jsxs("div", { children: ["Temp: ", currentState.tempScore] }), _jsxs("div", { children: ["Tint: ", currentState.tintScore] }), _jsxs("div", { children: ["Exposure: ", currentState.exposureScore] }), _jsxs("div", { children: ["Contrast: ", currentState.contrastScore] }), _jsxs("div", { children: ["Clarity: ", currentState.clarityScore] }), _jsxs("div", { children: ["Vibrance: ", currentState.vibranceScore] }), _jsxs("div", { children: ["Saturation: ", currentState.saturationScore] }), _jsxs("div", { children: ["Sharpness: ", currentState.sharpnessScore] })] }), _jsxs("div", { style: { marginTop: '10px', fontSize: '14px' }, children: [_jsx("strong", { children: "History:" }), " ", historyInfo.currentIndex + 1, " / ", historyInfo.totalStates, " |", _jsx("strong", { children: " Can Undo:" }), " ", historyInfo.canUndo ? 'Yes' : 'No', " |", _jsx("strong", { children: " Can Redo:" }), " ", historyInfo.canRedo ? 'Yes' : 'No'] })] }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "Load Saved Editing Session" }), _jsxs("div", { style: { display: 'flex', gap: '10px', marginBottom: '10px' }, children: [_jsx("button", { onClick: handleLoadSavedSession, style: { padding: '10px', backgroundColor: '#4CAF50', color: 'white', border: 'none' }, children: "Load Complete Session (5 steps)" }), _jsx("button", { onClick: handleLoadFromStorage, style: { padding: '10px', backgroundColor: '#2196F3', color: 'white', border: 'none' }, children: "Load from Storage" })] }), _jsxs("div", { style: { display: 'flex', gap: '5px' }, children: [_jsx("span", { style: { fontSize: '12px', marginRight: '10px' }, children: "Load to specific step:" }), savedHistoryData.map((_, index) => (_jsxs("button", { onClick: () => handleLoadToSpecificPoint(index), style: {
|
|
95
|
-
padding: '5px 10px',
|
|
96
|
-
backgroundColor: '#FF9800',
|
|
97
|
-
color: 'white',
|
|
98
|
-
border: 'none',
|
|
99
|
-
fontSize: '12px'
|
|
100
|
-
}, children: ["Step ", index + 1] }, index)))] })] }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "Load Preset Collections" }), _jsx("div", { style: { display: 'flex', gap: '10px' }, children: Object.keys(presetCollections).map(collectionName => (_jsxs("button", { onClick: () => handleLoadPresetCollection(collectionName), style: {
|
|
101
|
-
padding: '10px',
|
|
102
|
-
backgroundColor: '#9C27B0',
|
|
103
|
-
color: 'white',
|
|
104
|
-
border: 'none',
|
|
105
|
-
textTransform: 'capitalize'
|
|
106
|
-
}, children: [collectionName, " Collection"] }, collectionName))) }), _jsx("div", { style: { fontSize: '12px', color: '#666', marginTop: '5px' }, children: "Each collection contains 5 progressive adjustment steps" })] }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "History Management" }), _jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [_jsx("button", { onClick: handleExportHistory, style: { padding: '10px', backgroundColor: '#795548', color: 'white', border: 'none' }, children: "Export Current History" }), _jsx("button", { onClick: handleMergeStates, style: { padding: '10px', backgroundColor: '#607D8B', color: 'white', border: 'none' }, children: "Merge Additional States" }), _jsx("button", { onClick: actions.clearHistory, style: { padding: '10px', backgroundColor: '#f44336', color: 'white', border: 'none' }, children: "Clear History" })] })] }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "Navigation" }), _jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [_jsx("button", { onClick: actions.undo, disabled: !historyInfo.canUndo, style: {
|
|
107
|
-
padding: '10px',
|
|
108
|
-
backgroundColor: historyInfo.canUndo ? '#FF5722' : '#ccc',
|
|
109
|
-
color: 'white',
|
|
110
|
-
border: 'none'
|
|
111
|
-
}, children: "\u2190 Undo" }), _jsx("button", { onClick: actions.redo, disabled: !historyInfo.canRedo, style: {
|
|
112
|
-
padding: '10px',
|
|
113
|
-
backgroundColor: historyInfo.canRedo ? '#3F51B5' : '#ccc',
|
|
114
|
-
color: 'white',
|
|
115
|
-
border: 'none'
|
|
116
|
-
}, children: "Redo \u2192" })] })] }), _jsxs("div", { style: { fontSize: '12px', color: '#666', backgroundColor: '#f9f9f9', padding: '15px', borderRadius: '5px' }, children: [_jsx("h4", { children: "syncHistory Usage:" }), _jsxs("ul", { style: { margin: 0, paddingLeft: '20px' }, children: [_jsxs("li", { children: [_jsx("code", { children: "actions.syncHistory(states)" }), " - Replace entire history with new states, current = last"] }), _jsxs("li", { children: [_jsx("code", { children: "actions.syncHistory(states, index)" }), " - Replace history and set current to specific index"] }), _jsx("li", { children: "Automatically validates all states are valid AdjustmentState objects" }), _jsx("li", { children: "Respects maxSize limits and trims if needed" }), _jsx("li", { children: "Exits batch mode if currently active" }), _jsx("li", { children: "Perfect for loading saved sessions, preset collections, or API data" })] })] })] }));
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Real-world integration example
|
|
120
|
-
*/
|
|
121
|
-
export function RealWorldSyncExample() {
|
|
122
|
-
const history = useAdjustmentHistory(initialAdjustments);
|
|
123
|
-
// Example: Load editing session from API
|
|
124
|
-
const loadEditingSession = async (sessionId) => {
|
|
125
|
-
try {
|
|
126
|
-
// const response = await fetch(`/api/sessions/${sessionId}`);
|
|
127
|
-
// const sessionData = await response.json();
|
|
128
|
-
// Mock API response
|
|
129
|
-
const sessionData = [
|
|
130
|
-
{ ...initialAdjustments },
|
|
131
|
-
{ ...initialAdjustments, tempScore: 20, exposureScore: 15 },
|
|
132
|
-
{ ...initialAdjustments, tempScore: 20, exposureScore: 15, contrastScore: 25 },
|
|
133
|
-
];
|
|
134
|
-
history.actions.syncHistory(sessionData);
|
|
135
|
-
console.log('Loaded editing session:', sessionId);
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
console.error('Failed to load session:', error);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
// Example: Save current session to API
|
|
142
|
-
const saveEditingSession = async () => {
|
|
143
|
-
const currentHistory = history.actions.getHistory();
|
|
144
|
-
try {
|
|
145
|
-
// const response = await fetch('/api/sessions', {
|
|
146
|
-
// method: 'POST',
|
|
147
|
-
// headers: { 'Content-Type': 'application/json' },
|
|
148
|
-
// body: JSON.stringify({ history: currentHistory })
|
|
149
|
-
// });
|
|
150
|
-
console.log('Saved session with', currentHistory.length, 'states');
|
|
151
|
-
return 'session-123'; // Mock session ID
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
console.error('Failed to save session:', error);
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
// Example: Auto-save to localStorage
|
|
158
|
-
const autoSaveToLocalStorage = () => {
|
|
159
|
-
const currentHistory = history.actions.getHistory();
|
|
160
|
-
localStorage.setItem('adjustmentHistory', JSON.stringify(currentHistory));
|
|
161
|
-
localStorage.setItem('currentIndex', history.historyInfo.currentIndex.toString());
|
|
162
|
-
};
|
|
163
|
-
// Example: Load from localStorage on component mount
|
|
164
|
-
const loadFromLocalStorage = () => {
|
|
165
|
-
try {
|
|
166
|
-
const savedHistory = localStorage.getItem('adjustmentHistory');
|
|
167
|
-
const savedIndex = localStorage.getItem('currentIndex');
|
|
168
|
-
if (savedHistory) {
|
|
169
|
-
const parsedHistory = JSON.parse(savedHistory);
|
|
170
|
-
const targetIndex = savedIndex ? parseInt(savedIndex, 10) : undefined;
|
|
171
|
-
history.actions.syncHistory(parsedHistory, targetIndex);
|
|
172
|
-
console.log('Restored from localStorage');
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
console.error('Failed to load from localStorage:', error);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
return (_jsxs("div", { style: { padding: '20px' }, children: [_jsx("h2", { children: "Real-World syncHistory Integration" }), _jsxs("div", { style: { display: 'flex', gap: '10px', marginBottom: '20px' }, children: [_jsx("button", { onClick: () => loadEditingSession('session-123'), children: "Load Session from API" }), _jsx("button", { onClick: saveEditingSession, children: "Save Session to API" }), _jsx("button", { onClick: autoSaveToLocalStorage, children: "Save to LocalStorage" }), _jsx("button", { onClick: loadFromLocalStorage, children: "Load from LocalStorage" })] }), _jsxs("div", { style: { fontSize: '12px', color: '#666' }, children: [_jsx("p", { children: "This example shows how to integrate syncHistory with:" }), _jsxs("ul", { children: [_jsx("li", { children: "API endpoints for session management" }), _jsx("li", { children: "LocalStorage for offline persistence" }), _jsx("li", { children: "Auto-save functionality" }), _jsx("li", { children: "Session restoration on app load" })] })] })] }));
|
|
180
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Example usage of the useGallerySwipe hook
|
|
3
|
-
* This shows various integration patterns and use cases
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Basic example: Simple image gallery with navigation buttons
|
|
7
|
-
*/
|
|
8
|
-
export declare function BasicGalleryExample(): import("react/jsx-runtime").JSX.Element;
|
|
9
|
-
/**
|
|
10
|
-
* Advanced example: Gallery with keyboard navigation and swipe gestures
|
|
11
|
-
*/
|
|
12
|
-
export declare function AdvancedGalleryExample(): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
/**
|
|
14
|
-
* Integration example: Using with existing useHonchoEditor
|
|
15
|
-
*/
|
|
16
|
-
export declare function EditorIntegrationExample(): import("react/jsx-runtime").JSX.Element;
|
|
17
|
-
/**
|
|
18
|
-
* Mobile-optimized example with touch gestures
|
|
19
|
-
*/
|
|
20
|
-
export declare function MobileGalleryExample(): import("react/jsx-runtime").JSX.Element;
|
|
21
|
-
/**
|
|
22
|
-
* Error handling and loading states example
|
|
23
|
-
*/
|
|
24
|
-
export declare function ErrorHandlingExample(): import("react/jsx-runtime").JSX.Element;
|