@yogiswara/honcho-editor-ui 3.5.8 → 3.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.
@@ -4,19 +4,21 @@ import { Stack, Slider, Typography, Box } from "@mui/material";
4
4
  import useHonchoTypography from "../../themes/honchoTheme";
5
5
  import useColors from '../../themes/colors';
6
6
  import useSliderEvents from "../editor/sliderComponents/useSliderEvents";
7
- const formatValue = (value) => {
7
+ const formatValue = (value, isZeroBased = false) => {
8
+ if (isZeroBased)
9
+ return value.toString();
8
10
  if (value > 0)
9
11
  return `+${value}`;
10
12
  if (value < 0)
11
13
  return value.toString();
12
14
  return "0";
13
15
  };
14
- function useAdjustmentField(propValue, setValue, onDragStart, onDragEnd, isBatchMode) {
15
- const [local, setLocal] = useState(formatValue(propValue));
16
+ function useAdjustmentField(propValue, setValue, onDragStart, onDragEnd, isBatchMode, isZeroBased = false) {
17
+ const [local, setLocal] = useState(formatValue(propValue, isZeroBased));
16
18
  const [started, setStarted] = useState(false);
17
19
  // keep sync with external changes
18
20
  useEffect(() => {
19
- setLocal(formatValue(propValue));
21
+ setLocal(formatValue(propValue, isZeroBased));
20
22
  }, [propValue]);
21
23
  const handleChange = (e, min, max) => {
22
24
  const raw = e.target.value;
@@ -56,7 +58,7 @@ function useAdjustmentField(propValue, setValue, onDragStart, onDragEnd, isBatch
56
58
  if (isNaN(num))
57
59
  num = 0;
58
60
  num = Math.max(min, Math.min(max, num));
59
- setLocal(formatValue(num));
61
+ setLocal(formatValue(num, isZeroBased));
60
62
  setValue(num);
61
63
  }
62
64
  // end batch when user leaves field
@@ -82,7 +84,7 @@ export default function HSliderDetailsMobile(props) {
82
84
  const clarityRef = useSliderEvents(props.onDragStart, props.onDragEnd, props.isBatchMode);
83
85
  const sharpnessRef = useSliderEvents(props.onDragStart, props.onDragEnd, props.isBatchMode);
84
86
  const clarityInput = useAdjustmentField(props.clarityScore, (val) => props.onClarityChange("clarityScore", val), props.onDragStart, props.onDragEnd, props.isBatchMode);
85
- const sharpnessInput = useAdjustmentField(props.sharpnessScore, (val) => props.onSharpnessChange("sharpnessScore", val), props.onDragStart, props.onDragEnd, props.isBatchMode);
87
+ const sharpnessInput = useAdjustmentField(props.sharpnessScore, (val) => props.onSharpnessChange("sharpnessScore", val), props.onDragStart, props.onDragEnd, props.isBatchMode, true);
86
88
  return (_jsx(_Fragment, { children: _jsxs(Stack, { spacing: 0, direction: "column", sx: { width: '100%', paddingX: 1, m: "0px", userSelect: 'none' }, onTouchStart: (e) => e.stopPropagation(), children: [_jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px' }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface, userSelect: 'none' }, onDoubleClick: clarityInput.handleDoubleClick, children: "Clarity" }), _jsx(Typography, { sx: {
87
89
  ...typography.bodyMedium, // Use your standard typography
88
90
  color: colors.surface,
@@ -171,5 +173,5 @@ export default function HSliderDetailsMobile(props) {
171
173
  ref: sharpnessRef,
172
174
  onDoubleClick: sharpnessInput.handleDoubleClick
173
175
  }
174
- }, size: "small", value: props.sharpnessScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.onSharpnessChange("sharpnessScore", newValue) })] })] }) }));
176
+ }, size: "small", value: props.sharpnessScore, step: 1, min: 0, max: 100, onChange: (_event, newValue) => props.onSharpnessChange("sharpnessScore", newValue) })] })] }) }));
175
177
  }
@@ -41,12 +41,21 @@ export function useHonchoEditorSingle({ controller, initImageId, firebaseUid })
41
41
  }
42
42
  }, [gallerySwipe.isPrevAvailable, gallerySwipe.onSwipePrev]);
43
43
  const updateAdjustment = useCallback((field, value) => {
44
+ // Apply specific clamping for sharpness (0-100), others use -100 to 100
45
+ let clampedValue = value;
46
+ if (field === 'sharpnessScore') {
47
+ clampedValue = Math.max(0, Math.min(100, value));
48
+ }
49
+ else if (field !== 'preset_id') {
50
+ clampedValue = Math.max(-100, Math.min(100, value));
51
+ }
44
52
  const newState = {
45
53
  ...adjustmentHistory.currentState,
46
- [field]: value
54
+ [field]: clampedValue,
55
+ preset_id: undefined, // Clear preset_id when making manual adjustments
47
56
  };
48
57
  adjustmentHistory.actions.pushState(newState);
49
- }, [adjustmentHistory.currentState, adjustmentHistory.actions.pushState, adjustmentHistory.historyInfo.isBatchMode]);
58
+ }, [adjustmentHistory.currentState, adjustmentHistory.actions.pushState]);
50
59
  const setBatchMode = useCallback((enabled) => {
51
60
  adjustmentHistory.config.setBatchMode(enabled);
52
61
  }, [adjustmentHistory.config.setBatchMode]);
@@ -34,7 +34,7 @@ const convertColorAdjustmentToAdjustmentState = (colorAdjustment) => {
34
34
  whitesScore: colorAdjustment.whites,
35
35
  blacksScore: colorAdjustment.blacks,
36
36
  clarityScore: colorAdjustment.clarity,
37
- sharpnessScore: colorAdjustment.sharpness,
37
+ sharpnessScore: Math.max(0, Math.min(100, colorAdjustment.sharpness)),
38
38
  };
39
39
  };
40
40
  /**
@@ -188,22 +188,24 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
188
188
  }, [history.length, trimHistoryToSize]);
189
189
  // Push new state to history
190
190
  const pushState = useCallback((newState) => {
191
+ // Clamp sharpness to 0-100 before storing
192
+ const clampedState = {
193
+ ...newState,
194
+ sharpnessScore: Math.max(0, Math.min(100, newState.sharpnessScore || 0))
195
+ };
191
196
  // Always update currentState immediately for smooth UI
192
- currentStateRef.current = newState;
193
- setCurrentState(newState);
197
+ currentStateRef.current = clampedState;
198
+ setCurrentState(clampedState);
194
199
  if (batchModeRef.current) {
195
200
  // In batch mode: Don't update history yet, just update UI state
196
- // History will be updated when batch mode ends
197
- console.log(`[useAdjustmentHistory] Pushing state in batch mode:`, newState);
201
+ console.debug({ newState: clampedState }, '[useAdjustmentHistory] Pushing state in batch mode');
198
202
  return;
199
203
  }
200
204
  // Normal mode: Update history immediately
201
- console.log(`[useAdjustmentHistory] Pushing new state to history:`, newState);
205
+ console.debug({ newState: clampedState }, '[useAdjustmentHistory] Pushing new state to history');
202
206
  setHistory(prevHistory => {
203
207
  const truncatedHistory = prevHistory.slice(0, currentIndexRef.current + 1);
204
- // const taskId = `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
205
- // we put the taskId empty to check this state no need to save it
206
- const newHistory = [...truncatedHistory, { state: newState, taskId: "" }];
208
+ const newHistory = [...truncatedHistory, { state: clampedState, taskId: "" }];
207
209
  currentIndexRef.current = newHistory.length - 1;
208
210
  return newHistory;
209
211
  });
@@ -238,7 +238,11 @@ export function useAdjustmentHistoryBatch(controller, firebaseUid, eventId, opti
238
238
  const deltaValue = delta[key];
239
239
  if (typeof deltaValue === 'number' && key !== 'preset_id') {
240
240
  const currentValue = newAdjustment[key];
241
- newAdjustment[key] = Math.max(-100, Math.min(100, currentValue + deltaValue));
241
+ const newValue = currentValue + deltaValue;
242
+ // Sharpness has a range of 0-100, all others are -100 to 100
243
+ newAdjustment[key] = key === 'sharpnessScore'
244
+ ? Math.max(0, Math.min(100, newValue))
245
+ : Math.max(-100, Math.min(100, newValue));
242
246
  }
243
247
  });
244
248
  // Check if user is in the middle of history (not at latest state)
@@ -508,7 +512,10 @@ export function useAdjustmentHistoryBatch(controller, firebaseUid, eventId, opti
508
512
  Object.keys(clampedPreset).forEach(key => {
509
513
  const presetValue = clampedPreset[key];
510
514
  if (typeof presetValue === 'number' && key !== 'preset_id') {
511
- clampedPreset[key] = Math.max(-100, Math.min(100, presetValue));
515
+ // Sharpness has a range of 0-100, all others are -100 to 100
516
+ clampedPreset[key] = key === 'sharpnessScore'
517
+ ? Math.max(0, Math.min(100, presetValue))
518
+ : Math.max(-100, Math.min(100, presetValue));
512
519
  }
513
520
  });
514
521
  // Include the preset_id in the adjustment state
@@ -555,7 +562,10 @@ export function useAdjustmentHistoryBatch(controller, firebaseUid, eventId, opti
555
562
  const pasteValue = adjustments[key];
556
563
  if (typeof pasteValue === 'number' && key !== 'preset_id') {
557
564
  // Apply clamping to the pasted value
558
- newAdjustment[key] = Math.max(-100, Math.min(100, pasteValue));
565
+ // Sharpness has a range of 0-100, all others are -100 to 100
566
+ newAdjustment[key] = key === 'sharpnessScore'
567
+ ? Math.max(0, Math.min(100, pasteValue))
568
+ : Math.max(-100, Math.min(100, pasteValue));
559
569
  }
560
570
  else if (key === 'preset_id' && typeof pasteValue === 'string') {
561
571
  newAdjustment[key] = pasteValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yogiswara/honcho-editor-ui",
3
- "version": "3.5.8",
3
+ "version": "3.6.1",
4
4
  "description": "A complete UI component library for the Honcho photo editor.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",