@yogiswara/honcho-editor-ui 3.1.1 → 3.1.3

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.
@@ -1,9 +1,38 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
2
+ import { useEffect, useRef, useState } from "react";
3
3
  import { Stack, Slider, Typography } 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
+ function ThumbOnlySlider({ sx, slotProps, size, value, step, min, max, onChange, onDoubleClick, }) {
8
+ const wrapperRef = useRef(null);
9
+ useEffect(() => {
10
+ const wrapper = wrapperRef.current;
11
+ if (!wrapper)
12
+ return;
13
+ const handleInteractionStart = (event) => {
14
+ // Check if the element that was clicked is the thumb or is inside the thumb.
15
+ const isThumb = event.target.closest('.MuiSlider-thumb');
16
+ // If the click was NOT on the thumb, isThumb will be null.
17
+ if (!isThumb) {
18
+ // Stop the event dead in its tracks.
19
+ event.preventDefault();
20
+ event.stopPropagation();
21
+ }
22
+ };
23
+ // Manually attach the touchstart event with { passive: false }.
24
+ // This tells the browser it's "active", making preventDefault() valid.
25
+ wrapper.addEventListener('pointerdown', handleInteractionStart);
26
+ // Cleanup function
27
+ return () => {
28
+ // ✅ Simplified cleanup
29
+ wrapper.removeEventListener('pointerdown', handleInteractionStart);
30
+ };
31
+ }, []);
32
+ return (
33
+ // This wrapper div catches the event before the Slider can.
34
+ _jsx("div", { ref: wrapperRef, children: _jsx(Slider, { sx: sx, slotProps: slotProps, size: size, value: value, step: step, min: min, max: max, onChange: onChange, onDoubleClick: onDoubleClick }) }));
35
+ }
7
36
  const formatValue = (value) => {
8
37
  if (value > 0)
9
38
  return `+${value}`;
@@ -79,15 +108,6 @@ function useAdjustmentField(propValue, setValue, onDragStart, onDragEnd, isBatch
79
108
  export default function HSliderColorMobile(props) {
80
109
  const typography = useHonchoTypography();
81
110
  const colors = useColors();
82
- console.log(`[HSliderColorMobile TEMPERATURE] Received tempScore prop: ${props.tempScore}`);
83
- const handleDragStartWithLog = () => {
84
- console.log('[HSliderColorMobile TEMPERATURE] SLIDER onDragStart triggered.');
85
- props.onDragStart();
86
- };
87
- const handleDragEndWithLog = () => {
88
- console.log('[HSliderColorMobile TEMPERATURE] SLIDER onDragEnd triggered.');
89
- props.onDragEnd();
90
- };
91
111
  const tempSliderRef = useSliderEvents(props.onDragStart, props.onDragEnd, props.isBatchMode);
92
112
  const tintSliderRef = useSliderEvents(props.onDragStart, props.onDragEnd, props.isBatchMode);
93
113
  const vibranceSliderRef = useSliderEvents(props.onDragStart, props.onDragEnd, props.isBatchMode);
@@ -123,108 +143,40 @@ export default function HSliderColorMobile(props) {
123
143
  color: colors.surface,
124
144
  width: "40px", // Keep the fixed width for alignment
125
145
  textAlign: "right", // Keep the text alignment
126
- }, children: formatValue(props.tempScore) })] }), _jsx(Slider, { sx: {
127
- width: "100%",
128
- color: colors.surface,
129
- '& .MuiSlider-rail': {
130
- background: tempGradient,
131
- opacity: 1,
132
- pointerEvents: 'none', // Make the rail non-interactive
133
- },
134
- '& .MuiSlider-track': {
135
- background: 'transparent',
136
- border: 'none',
137
- pointerEvents: 'none', // Make the track non-interactive
138
- },
139
- '& .MuiSlider-thumb': {
140
- boxShadow: 'none',
141
- pointerEvents: 'auto', // IMPORTANT: Re-enable interaction ONLY for the thumb
142
- touchAction: 'none',
143
- }
144
- }, slotProps: {
145
- thumb: {
146
- ref: tempSliderRef
147
- }
148
- }, size: "small", value: props.tempScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setTempScore("tempScore", newValue), onDoubleClick: tempInput.handleDoubleClick }), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px', '&:focus-within .MuiFilledInput-input': focusedInputStyle }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface }, onDoubleClick: tintInput.handleDoubleClick, children: "Tint" }), _jsx(Typography, { sx: {
146
+ }, children: formatValue(props.tempScore) })] }), _jsx(ThumbOnlySlider, { sx: {
147
+ width: "100%", color: colors.surface,
148
+ '& .MuiSlider-rail': { background: tempGradient, opacity: 1 },
149
+ '& .MuiSlider-track': { background: 'transparent', border: 'none' },
150
+ '& .MuiSlider-thumb': { boxShadow: 'none', touchAction: 'none' }
151
+ }, slotProps: { thumb: { ref: tempSliderRef } }, size: "small", value: props.tempScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setTempScore("tempScore", newValue), onDoubleClick: tempInput.handleDoubleClick }), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px', '&:focus-within .MuiFilledInput-input': focusedInputStyle }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface }, onDoubleClick: tintInput.handleDoubleClick, children: "Tint" }), _jsx(Typography, { sx: {
149
152
  ...typography.bodyMedium, // Use your standard typography
150
153
  color: colors.surface,
151
154
  width: "40px", // Keep the fixed width for alignment
152
155
  textAlign: "right", // Keep the text alignment
153
- }, children: formatValue(props.tintScore) })] }), _jsx(Slider, { sx: {
154
- width: "100%",
155
- color: colors.surface,
156
- '& .MuiSlider-rail': {
157
- background: tintGradient,
158
- opacity: 1,
159
- pointerEvents: 'none',
160
- },
161
- '& .MuiSlider-track': {
162
- background: 'transparent',
163
- border: 'none',
164
- pointerEvents: 'none',
165
- },
166
- '& .MuiSlider-thumb': {
167
- boxShadow: 'none',
168
- pointerEvents: 'auto',
169
- touchAction: 'none',
170
- }
171
- }, slotProps: {
172
- thumb: {
173
- ref: tintSliderRef
174
- }
175
- }, size: "small", value: props.tintScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setTintScore("tintScore", newValue), onDoubleClick: tintInput.handleDoubleClick }), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px', '&:focus-within .MuiFilledInput-input': focusedInputStyle }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface }, onDoubleClick: vibranceInput.handleDoubleClick, children: "Vibrance" }), _jsx(Typography, { sx: {
156
+ }, children: formatValue(props.tintScore) })] }), _jsx(ThumbOnlySlider, { sx: {
157
+ width: "100%", color: colors.surface,
158
+ '& .MuiSlider-rail': { background: tintGradient, opacity: 1 },
159
+ '& .MuiSlider-track': { background: 'transparent', border: 'none' },
160
+ '& .MuiSlider-thumb': { boxShadow: 'none', touchAction: 'none' }
161
+ }, slotProps: { thumb: { ref: tintSliderRef } }, size: "small", value: props.tintScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setTintScore("tintScore", newValue), onDoubleClick: tintInput.handleDoubleClick }), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px', '&:focus-within .MuiFilledInput-input': focusedInputStyle }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface }, onDoubleClick: vibranceInput.handleDoubleClick, children: "Vibrance" }), _jsx(Typography, { sx: {
176
162
  ...typography.bodyMedium, // Use your standard typography
177
163
  color: colors.surface,
178
164
  width: "40px", // Keep the fixed width for alignment
179
165
  textAlign: "right", // Keep the text alignment
180
- }, children: formatValue(props.vibranceScore) })] }), _jsx(Slider, { sx: {
181
- width: "100%",
182
- color: colors.surface,
183
- '& .MuiSlider-rail': {
184
- background: fullTrackGradient,
185
- opacity: 1,
186
- pointerEvents: 'none',
187
- },
188
- '& .MuiSlider-track': {
189
- background: 'transparent',
190
- border: 'none',
191
- pointerEvents: 'none',
192
- },
193
- '& .MuiSlider-thumb': {
194
- boxShadow: 'none',
195
- pointerEvents: 'auto',
196
- touchAction: 'none',
197
- }
198
- }, slotProps: {
199
- thumb: {
200
- ref: vibranceSliderRef
201
- }
202
- }, size: "small", value: props.vibranceScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setVibranceScore("vibranceScore", newValue), onDoubleClick: vibranceInput.handleDoubleClick }), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px', '&:focus-within .MuiFilledInput-input': focusedInputStyle }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface }, onDoubleClick: saturationInput.handleDoubleClick, children: "Saturation" }), _jsx(Typography, { sx: {
166
+ }, children: formatValue(props.vibranceScore) })] }), _jsx(ThumbOnlySlider, { sx: {
167
+ width: "100%", color: colors.surface,
168
+ '& .MuiSlider-rail': { background: fullTrackGradient, opacity: 1 },
169
+ '& .MuiSlider-track': { background: 'transparent', border: 'none' },
170
+ '& .MuiSlider-thumb': { boxShadow: 'none', touchAction: 'none' }
171
+ }, slotProps: { thumb: { ref: vibranceSliderRef } }, size: "small", value: props.vibranceScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setVibranceScore("vibranceScore", newValue), onDoubleClick: vibranceInput.handleDoubleClick }), _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { pt: '10px', pb: '0px', '&:focus-within .MuiFilledInput-input': focusedInputStyle }, children: [_jsx(Typography, { sx: { ...typography.bodyMedium, color: colors.surface }, onDoubleClick: saturationInput.handleDoubleClick, children: "Saturation" }), _jsx(Typography, { sx: {
203
172
  ...typography.bodyMedium, // Use your standard typography
204
173
  color: colors.surface,
205
174
  width: "40px", // Keep the fixed width for alignment
206
175
  textAlign: "right", // Keep the text alignment
207
- }, children: formatValue(props.saturationScore) })] }), _jsx(Slider, { sx: {
208
- width: "100%",
209
- color: colors.surface,
210
- '& .MuiSlider-rail': {
211
- background: fullTrackGradient,
212
- opacity: 1,
213
- pointerEvents: 'none',
214
- },
215
- '& .MuiSlider-track': {
216
- background: 'transparent',
217
- border: 'none',
218
- pointerEvents: 'none',
219
- },
220
- '& .MuiSlider-thumb': {
221
- boxShadow: 'none',
222
- pointerEvents: 'auto',
223
- touchAction: 'none',
224
- }
225
- }, slotProps: {
226
- thumb: {
227
- ref: saturationSliderRef
228
- }
229
- }, size: "small", value: props.saturationScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setSaturationScore("saturationScore", newValue), onDoubleClick: saturationInput.handleDoubleClick })] }) }));
176
+ }, children: formatValue(props.saturationScore) })] }), _jsx(ThumbOnlySlider, { sx: {
177
+ width: "100%", color: colors.surface,
178
+ '& .MuiSlider-rail': { background: fullTrackGradient, opacity: 1 },
179
+ '& .MuiSlider-track': { background: 'transparent', border: 'none' },
180
+ '& .MuiSlider-thumb': { boxShadow: 'none', touchAction: 'none' }
181
+ }, slotProps: { thumb: { ref: saturationSliderRef } }, size: "small", value: props.saturationScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setSaturationScore("saturationScore", newValue), onDoubleClick: saturationInput.handleDoubleClick })] }) }));
230
182
  }
@@ -0,0 +1,5 @@
1
+ import { SliderProps } from '@mui/material';
2
+ interface HThumbSliderProps extends SliderProps {
3
+ }
4
+ export default function HThumbSlider(props: HThumbSliderProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useRef, useEffect } from 'react';
3
+ import { Slider } from '@mui/material';
4
+ export default function HThumbSlider(props) {
5
+ const wrapperRef = useRef(null);
6
+ useEffect(() => {
7
+ const wrapper = wrapperRef.current;
8
+ if (!wrapper)
9
+ return;
10
+ const handleInteractionStart = (event) => {
11
+ // Check if the element that was clicked is the thumb
12
+ const isThumb = event.target.closest('.MuiSlider-thumb');
13
+ // If the click was NOT on the thumb, stop the event
14
+ if (!isThumb) {
15
+ event.preventDefault();
16
+ event.stopPropagation();
17
+ }
18
+ };
19
+ // Manually attach an "active" touchstart listener to prevent console warnings
20
+ wrapper.addEventListener('pointerdown', handleInteractionStart);
21
+ // Cleanup function
22
+ return () => {
23
+ // ✅ Simplified cleanup
24
+ wrapper.removeEventListener('pointerdown', handleInteractionStart);
25
+ };
26
+ }, []);
27
+ return (
28
+ // The wrapper div catches the event before the Slider can.
29
+ _jsx("div", { ref: wrapperRef, children: _jsx(Slider, { ...props }) }));
30
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yogiswara/honcho-editor-ui",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
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",