@yogiswara/honcho-editor-ui 2.11.1 → 2.11.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,23 +1,52 @@
1
1
  import React from "react";
2
- type SubTab = {
3
- value: string;
4
- label: string;
5
- inactiveIcon?: string;
6
- activeIcon?: string;
2
+ import { AdjustmentState } from '../../hooks/editor/type';
3
+ type Preset = {
4
+ id: string;
5
+ name: string;
7
6
  };
8
7
  interface Props {
9
- activePanelMobile: string;
8
+ presets: Preset[];
9
+ activePanel: string;
10
10
  activeSubPanel: string;
11
- setActivePanelMobile: (tab: string) => void;
11
+ setActivePanel: (tab: string) => void;
12
12
  setActiveSubPanel: (subTab: string) => void;
13
- subTabs: {
14
- [key: string]: SubTab[];
15
- };
16
- panelContent: React.ReactNode;
13
+ innerRef?: React.Ref<HTMLDivElement>;
17
14
  panelRef: React.RefObject<HTMLDivElement>;
18
15
  contentRef: React.RefObject<HTMLDivElement | null>;
19
16
  panelHeight: number;
20
17
  handleDragStart: (e: React.MouseEvent | React.TouchEvent) => void;
18
+ onContentHeightChange: (height: number) => void;
19
+ tempScore: number;
20
+ tintScore: number;
21
+ vibranceScore: number;
22
+ saturationScore: number;
23
+ exposureScore: number;
24
+ highlightsScore: number;
25
+ shadowScore: number;
26
+ whiteScore: number;
27
+ blackScore: number;
28
+ contrastScore: number;
29
+ clarityScore: number;
30
+ sharpnessScore: number;
31
+ setTempScore: (field: keyof AdjustmentState, value: number) => void;
32
+ setTintScore: (field: keyof AdjustmentState, value: number) => void;
33
+ setVibranceScore: (field: keyof AdjustmentState, value: number) => void;
34
+ setSaturationScore: (field: keyof AdjustmentState, value: number) => void;
35
+ onExposureChange: (field: keyof AdjustmentState, value: number) => void;
36
+ onHighlightsChange: (field: keyof AdjustmentState, value: number) => void;
37
+ onShadowsChange: (field: keyof AdjustmentState, value: number) => void;
38
+ onWhitesChange: (field: keyof AdjustmentState, value: number) => void;
39
+ onBlacksChange: (field: keyof AdjustmentState, value: number) => void;
40
+ onContrastChange: (field: keyof AdjustmentState, value: number) => void;
41
+ onClarityChange: (field: keyof AdjustmentState, value: number) => void;
42
+ onSharpnessChange: (field: keyof AdjustmentState, value: number) => void;
43
+ isBatchMode: boolean;
44
+ onDragStart: () => void;
45
+ onDragEnd: () => void;
46
+ selectedPreset: string | null;
47
+ onSelectPreset: (id: string) => void;
48
+ onOpenPresetModal: () => void;
49
+ presetOptionModal: (event: React.MouseEvent<HTMLElement>, presetId: string) => void;
21
50
  }
22
51
  export default function HImageEditorMobile(props: Props): import("react/jsx-runtime").JSX.Element;
23
52
  export {};
@@ -1,25 +1,43 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Paper, Stack, BottomNavigation, BottomNavigationAction, CardMedia } from "@mui/material";
2
+ import { BottomNavigation, BottomNavigationAction, Box, CardMedia, Paper, Stack } from "@mui/material";
3
+ import useHonchoTypography from "../../themes/honchoTheme";
4
+ import useColors from '../../themes/colors';
5
+ import HTabColorAdjustmentMobile from "./HTabColorAdjustmentMobile";
6
+ import HTabPresetMobile from "./HTabPresetMobile";
7
+ // Data structure for the sub-navigation tabs
8
+ const subTabs = {
9
+ colorAdjustment: [
10
+ { value: "color", label: "Color", inactiveIcon: "/v1/svg/new-mobile-coloAdjustment-notpress.svg", activeIcon: "/v1/svg/new-mobile-coloAdjustment-presssvg.svg" },
11
+ { value: "light", label: "Light", inactiveIcon: "/v1/svg/light-inactive-mobile.svg", activeIcon: "/v1/svg/light-active-mobile.svg" },
12
+ // { value: "details", label: "Details", inactiveIcon: "/v1/svg/details-inactive-mobile.svg", activeIcon: "/v1/svg/details-active-mobile.svg"},
13
+ ],
14
+ aspectRatio: [
15
+ { value: "portrait", label: "Portrait" },
16
+ { value: "square", label: "Square" },
17
+ { value: "wide", label: "Wide" },
18
+ ],
19
+ preset: [
20
+ { value: "Preset", label: "Preset", inactiveIcon: "/v1/svg/preset-inactive-mobile.svg", activeIcon: "/v1/svg/preset-active-mobile.svg" },
21
+ ],
22
+ };
3
23
  export default function HImageEditorMobile(props) {
24
+ const typography = useHonchoTypography();
25
+ const colors = useColors();
26
+ console.log(`[HImageEditorMobile TEMPERATURE] Rendering with tempScore: ${props.tempScore}, isBatchMode: ${props.isBatchMode}`);
4
27
  const handleChange = (event, newValue) => {
5
- props.setActivePanelMobile(newValue);
28
+ props.setActivePanel(newValue);
6
29
  };
7
- // This function is now back inside the component
8
- const renderSubNavigation = () => {
9
- const currentSubTabs = props.subTabs[props.activePanelMobile];
10
- if (!currentSubTabs)
11
- return null;
12
- return (_jsx(Paper, { sx: { backgroundColor: 'black', borderRadius: "0px", px: "44px" }, elevation: 3, children: _jsx(BottomNavigation, { showLabels: true, sx: { backgroundColor: 'black', gap: '10px' }, children: currentSubTabs.map((tab) => {
13
- const isActive = props.activeSubPanel === tab.value;
14
- const iconSrc = isActive ? tab.activeIcon : tab.inactiveIcon;
15
- return (_jsx(BottomNavigationAction, { label: tab.label, value: tab.value, onClick: () => props.setActiveSubPanel(isActive ? '' : tab.value), icon: iconSrc && _jsx(CardMedia, { component: "img", image: iconSrc, sx: { width: "20px", height: "20px", mb: "5px" } }), sx: {
16
- color: isActive ? 'white' : 'grey',
17
- minWidth: 'auto', p: 0,
18
- '& .MuiBottomNavigationAction-label': {
19
- color: isActive ? 'white' : 'grey',
20
- }
21
- } }, tab.value));
22
- }) }) }));
30
+ const currentSubTabs = subTabs[props.activePanel];
31
+ // Helper function to render the correct content inside the draggable panel
32
+ const renderPanelContent = () => {
33
+ switch (props.activePanel) {
34
+ case 'colorAdjustment':
35
+ return _jsx(HTabColorAdjustmentMobile, { activeSubPanel: props.activeSubPanel, innerRef: props.innerRef, onDragStart: props.onDragStart, onDragEnd: props.onDragEnd, onExposureChange: props.onExposureChange, onContrastChange: props.onContrastChange, onHighlightsChange: props.onHighlightsChange, onShadowsChange: props.onShadowsChange, onWhitesChange: props.onWhitesChange, onBlacksChange: props.onBlacksChange, setTempScore: props.setTempScore, setTintScore: props.setTintScore, setVibranceScore: props.setVibranceScore, setSaturationScore: props.setSaturationScore, exposureScore: props.exposureScore, contrastScore: props.contrastScore, highlightsScore: props.highlightsScore, shadowScore: props.shadowScore, whiteScore: props.whiteScore, blackScore: props.blackScore, tempScore: props.tempScore, tintScore: props.tintScore, vibranceScore: props.vibranceScore, saturationScore: props.saturationScore, isBatchMode: props.isBatchMode, sharpnessScore: props.sharpnessScore, onSharpnessChange: props.onSharpnessChange, clarityScore: props.clarityScore, onClarityChange: props.onClarityChange });
36
+ case 'preset':
37
+ return _jsx(HTabPresetMobile, { ...props });
38
+ default:
39
+ return null;
40
+ }
23
41
  };
24
42
  return (_jsx(Paper, { elevation: 0, sx: {
25
43
  id: 'HImageEditorMobile',
@@ -53,5 +71,23 @@ export default function HImageEditorMobile(props) {
53
71
  overflowY: 'auto',
54
72
  scrollbarWidth: 'none',
55
73
  '&::-webkit-scrollbar': { display: 'none' },
56
- }, children: props.panelContent })] })), renderSubNavigation()] }) }));
74
+ }, children: renderPanelContent() })] })), currentSubTabs && (_jsx(Paper, { sx: {
75
+ backgroundColor: colors.onBackground,
76
+ paddingTop: "10px",
77
+ pb: "0px",
78
+ mb: "0px",
79
+ px: "44px",
80
+ borderRadius: "0px",
81
+ }, elevation: 3, children: _jsx(BottomNavigation, { showLabels: true, sx: { backgroundColor: colors.onBackground, gap: '10px' }, children: currentSubTabs.map((tab) => {
82
+ const isActive = props.activeSubPanel === tab.value;
83
+ const iconSrc = isActive ? tab.activeIcon : tab.inactiveIcon;
84
+ return (_jsx(BottomNavigationAction, { label: tab.label, value: tab.value, onClick: () => props.setActiveSubPanel(isActive ? '' : tab.value), icon: iconSrc && _jsx(CardMedia, { component: "img", image: iconSrc, sx: { width: "20px", height: "20px", mb: "5px" } }), sx: {
85
+ color: isActive ? colors.surface : colors.onSurfaceVariant1,
86
+ minWidth: 'auto', p: 0,
87
+ '& .MuiBottomNavigationAction-label': {
88
+ ...typography.labelSmall,
89
+ color: isActive ? colors.surface : colors.onSurfaceVariant1,
90
+ }
91
+ } }, tab.value));
92
+ }) }) })), _jsx(Paper, { sx: { backgroundColor: colors.onBackground, borderRadius: "0px" }, elevation: 3, children: _jsx(Stack, { direction: "row", justifyContent: "center", alignItems: "center", sx: { pt: "0px", pb: "0px", mb: "0px", mr: "0px", ml: "0px" }, children: _jsxs(BottomNavigation, { value: props.activePanel, onChange: handleChange, sx: { backgroundColor: colors.onBackground }, children: [_jsx(BottomNavigationAction, { value: "colorAdjustment", sx: { px: '12px', py: '0px', minWidth: 'auto' }, icon: _jsx(CardMedia, { component: "img", image: props.activePanel === 'colorAdjustment' ? "/v1/svg/color-adjustment-active-mobile.svg" : "/v1/svg/color-adjustment-inactive-mobile.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(BottomNavigationAction, { value: "preset", sx: { px: '12px', py: '0px', minWidth: 'auto' }, icon: _jsx(CardMedia, { component: "img", image: props.activePanel === 'preset' ? "/v1/svg/preset-and-watermark-active-mobile.svg" : "/v1/svg/preset-and-watermark-inactive-mobile.svg", sx: { width: "20px", height: "20px" } }) })] }) }) })] }) }));
57
93
  }
@@ -123,7 +123,7 @@ export default function HSliderColorMobile(props) {
123
123
  color: colors.surface,
124
124
  width: "40px", // Keep the fixed width for alignment
125
125
  textAlign: "right", // Keep the text alignment
126
- }, children: formatValue(props.tempScore) })] }), _jsx(Slider, { ref: tempSliderRef, sx: {
126
+ }, children: formatValue(props.tempScore) })] }), _jsx(Slider, { sx: {
127
127
  width: "100%",
128
128
  color: colors.surface,
129
129
  '& .MuiSlider-rail': {
@@ -140,12 +140,16 @@ export default function HSliderColorMobile(props) {
140
140
  boxShadow: 'none',
141
141
  pointerEvents: 'auto', // IMPORTANT: Re-enable interaction ONLY for the thumb
142
142
  }
143
+ }, slotProps: {
144
+ thumb: {
145
+ ref: tempSliderRef
146
+ }
143
147
  }, 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: {
144
148
  ...typography.bodyMedium, // Use your standard typography
145
149
  color: colors.surface,
146
150
  width: "40px", // Keep the fixed width for alignment
147
151
  textAlign: "right", // Keep the text alignment
148
- }, children: formatValue(props.tintScore) })] }), _jsx(Slider, { ref: tintSliderRef, sx: {
152
+ }, children: formatValue(props.tintScore) })] }), _jsx(Slider, { sx: {
149
153
  width: "100%",
150
154
  color: colors.surface,
151
155
  '& .MuiSlider-rail': {
@@ -162,12 +166,16 @@ export default function HSliderColorMobile(props) {
162
166
  boxShadow: 'none',
163
167
  pointerEvents: 'auto',
164
168
  }
169
+ }, slotProps: {
170
+ thumb: {
171
+ ref: tintSliderRef
172
+ }
165
173
  }, 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: {
166
174
  ...typography.bodyMedium, // Use your standard typography
167
175
  color: colors.surface,
168
176
  width: "40px", // Keep the fixed width for alignment
169
177
  textAlign: "right", // Keep the text alignment
170
- }, children: formatValue(props.vibranceScore) })] }), _jsx(Slider, { ref: vibranceSliderRef, sx: {
178
+ }, children: formatValue(props.vibranceScore) })] }), _jsx(Slider, { sx: {
171
179
  width: "100%",
172
180
  color: colors.surface,
173
181
  '& .MuiSlider-rail': {
@@ -184,12 +192,16 @@ export default function HSliderColorMobile(props) {
184
192
  boxShadow: 'none',
185
193
  pointerEvents: 'auto',
186
194
  }
195
+ }, slotProps: {
196
+ thumb: {
197
+ ref: vibranceSliderRef
198
+ }
187
199
  }, 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: {
188
200
  ...typography.bodyMedium, // Use your standard typography
189
201
  color: colors.surface,
190
202
  width: "40px", // Keep the fixed width for alignment
191
203
  textAlign: "right", // Keep the text alignment
192
- }, children: formatValue(props.saturationScore) })] }), _jsx(Slider, { ref: saturationSliderRef, sx: {
204
+ }, children: formatValue(props.saturationScore) })] }), _jsx(Slider, { sx: {
193
205
  width: "100%",
194
206
  color: colors.surface,
195
207
  '& .MuiSlider-rail': {
@@ -206,5 +218,9 @@ export default function HSliderColorMobile(props) {
206
218
  boxShadow: 'none',
207
219
  pointerEvents: 'auto',
208
220
  }
221
+ }, slotProps: {
222
+ thumb: {
223
+ ref: saturationSliderRef
224
+ }
209
225
  }, size: "small", value: props.saturationScore, step: 1, min: -100, max: 100, onChange: (_event, newValue) => props.setSaturationScore("saturationScore", newValue), onDoubleClick: saturationInput.handleDoubleClick })] }) }));
210
226
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yogiswara/honcho-editor-ui",
3
- "version": "2.11.1",
3
+ "version": "2.11.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",