@yogiswara/honcho-editor-ui 3.4.10 → 3.4.12

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.
@@ -5,14 +5,14 @@ import useColors from '../../themes/colors';
5
5
  import useIsMobile from "../../utils/isMobile";
6
6
  import { MinusCirlce, TickCircle } from "iconsax-react";
7
7
  export default function HHeaderEditor(props) {
8
- props.totalCount = props.totalCount || 0;
9
- props.selectedCount = props.selectedCount || 0;
8
+ const totalCount = props.totalCount || 0;
9
+ const selectedCount = props.selectedCount || 0;
10
10
  const typography = useHonchoTypography();
11
11
  const colors = useColors();
12
12
  const open = Boolean(props.anchorEl);
13
13
  const isMobile = useIsMobile();
14
- const isAllSelected = props.selectedCount === props.totalCount && props.totalCount > 0;
15
- const isPartiallySelected = props.selectedCount > 0 && props.selectedCount < props.totalCount;
14
+ const isAllSelected = selectedCount === totalCount && totalCount > 0;
15
+ const isPartiallySelected = selectedCount > 0 && selectedCount < totalCount;
16
16
  return (_jsx(_Fragment, { children: _jsxs(Stack, { direction: "row", justifyContent: "space-between", width: "100%", sx: {
17
17
  id: 'HHeaderEditor',
18
18
  pr: !isMobile ? "24px" : "6px",
@@ -48,7 +48,21 @@ export default function HHeaderEditor(props) {
48
48
  border: `1px solid ${colors.outlineVariant}`,
49
49
  },
50
50
  },
51
- }, children: [_jsxs(MenuItem, { onClick: props.onRevert, children: [_jsx(ListItemIcon, { sx: { minWidth: 0, mr: "0px", px: "0px" }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/revert-editor.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(ListItemText, { children: _jsx(Typography, { sx: { fontSize: "14px", color: colors.surface }, children: "Revert to original" }) })] }), _jsxs(MenuItem, { onClick: props.onCopyEdit, disabled: !props.isCopyEnabled, children: [_jsx(ListItemIcon, { sx: { minWidth: 0, mr: "0px", px: "0px" }, children: _jsx(CardMedia, { component: "img", image: !props.isCopyEnabled ? "/v1/svg/copy-editor-grey.svg" : "/v1/svg/copy-editor.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(ListItemText, { children: _jsx(Typography, { sx: { fontSize: "14px", color: !props.isCopyEnabled ? colors.onSurfaceVariant : colors.surface }, children: "Copy edits" }) }), !isMobile &&
52
- _jsx(ListItemIcon, { sx: { marginLeft: 'auto' }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/shortcut-copy-editor.svg", sx: { width: "25px", height: "20px" } }) })] }), _jsxs(MenuItem, { onClick: props.onPasteEdit, disabled: !props.isPasteEnabled, children: [_jsx(ListItemIcon, { sx: { minWidth: 0, mr: "0px", px: "0px" }, children: _jsx(CardMedia, { component: "img", image: !props.isPasteEnabled ? "/v1/svg/paste-editor.svg" : "/v1/svg/paste-white.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(ListItemText, { children: _jsx(Typography, { sx: { fontSize: "14px", color: !props.isPasteEnabled ? colors.onSurfaceVariant : colors.surface }, children: "Paste edits" }) }), !isMobile &&
51
+ }, children: [_jsxs(MenuItem, { onClick: props.onRevert, children: [_jsx(ListItemIcon, { sx: { minWidth: 0, mr: "0px", px: "0px" }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/revert-editor.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(ListItemText, { children: _jsx(Typography, { sx: { fontSize: "14px", color: colors.surface }, children: "Revert to original" }) })] }), _jsxs(MenuItem, { onClick: props.onCopyEdit, disabled: !props.isCopyEnabled, sx: {
52
+ '&.Mui-disabled': {
53
+ opacity: 1, // Prevent default opacity reduction
54
+ },
55
+ '&.Mui-disabled .MuiTypography-root': {
56
+ color: `${!props.isCopyEnabled ? colors.onSurfaceVariant1 : colors.surface} !important`,
57
+ }
58
+ }, children: [_jsx(ListItemIcon, { sx: { minWidth: 0, mr: "0px", px: "0px" }, children: _jsx(CardMedia, { component: "img", image: !props.isCopyEnabled ? "/v1/svg/copy-editor-grey.svg" : "/v1/svg/copy-editor.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(ListItemText, { children: _jsx(Typography, { sx: { fontSize: "14px", color: !props.isCopyEnabled ? colors.onSurfaceVariant : colors.surface }, children: "Copy edits" }) }), !isMobile &&
59
+ _jsx(ListItemIcon, { sx: { marginLeft: 'auto' }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/shortcut-copy-editor.svg", sx: { width: "25px", height: "20px" } }) })] }), _jsxs(MenuItem, { onClick: props.onPasteEdit, disabled: !props.isPasteEnabled, sx: {
60
+ '&.Mui-disabled': {
61
+ opacity: 1, // Prevent default opacity reduction
62
+ },
63
+ '&.Mui-disabled .MuiTypography-root': {
64
+ color: `${!props.isPasteEnabled ? colors.onSurfaceVariant1 : colors.surface} !important`,
65
+ }
66
+ }, children: [_jsx(ListItemIcon, { sx: { minWidth: 0, mr: "0px", px: "0px" }, children: _jsx(CardMedia, { component: "img", image: !props.isPasteEnabled ? "/v1/svg/paste-editor.svg" : "/v1/svg/paste-white.svg", sx: { width: "20px", height: "20px" } }) }), _jsx(ListItemText, { children: _jsx(Typography, { sx: { fontSize: "14px", color: !props.isPasteEnabled ? colors.onSurfaceVariant : colors.surface }, children: "Paste edits" }) }), !isMobile &&
53
67
  _jsx(ListItemIcon, { sx: { marginLeft: '30px' }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/shortcut-paste-editor.svg", sx: { width: "25px", height: "20px" } }) })] })] })] })] }) }));
54
68
  }
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
  import { useState, useEffect, useRef, useCallback } from 'react';
3
3
  import { loadImageAsFile } from '../../utils/imageLoader';
4
+ import { log } from '../../utils/logger';
4
5
  export function useEditorHeadless(options = {}) {
5
6
  const { scriptUrl = '/honcho-photo-editor.js', wasmUrl = '/honcho-photo-editor.wasm' } = options;
6
7
  const editorRef = useRef(null);
@@ -12,7 +13,7 @@ export function useEditorHeadless(options = {}) {
12
13
  const loadScripts = async () => {
13
14
  // Check if HonchoEditor is already available
14
15
  if (window.HonchoEditor) {
15
- console.debug('HonchoEditor already available globally');
16
+ log.debug('HonchoEditor already available globally');
16
17
  setIsScriptLoaded(true);
17
18
  return;
18
19
  }
@@ -21,20 +22,20 @@ export function useEditorHeadless(options = {}) {
21
22
  return new Promise((resolve, reject) => {
22
23
  // Check if WASM module is already loaded
23
24
  if (document.querySelector(`script[src="${scriptUrl}"]`)) {
24
- console.debug('WASM module script already exists');
25
+ log.debug('WASM module script already exists');
25
26
  resolve();
26
27
  return;
27
28
  }
28
- console.debug(`Loading WASM module from: ${scriptUrl}`);
29
+ log.debug({ scriptUrl }, 'Loading WASM module from URL');
29
30
  const wasmScript = document.createElement('script');
30
31
  wasmScript.src = scriptUrl;
31
32
  wasmScript.async = true;
32
33
  wasmScript.onload = () => {
33
- console.debug('WASM module script loaded');
34
+ log.debug('WASM module script loaded');
34
35
  resolve();
35
36
  };
36
37
  wasmScript.onerror = () => {
37
- console.error(`Failed to load WASM module from: ${scriptUrl}`);
38
+ log.error({ scriptUrl }, 'Failed to load WASM module from URL');
38
39
  reject(new Error('Failed to load WASM module'));
39
40
  };
40
41
  document.head.appendChild(wasmScript);
@@ -46,20 +47,20 @@ export function useEditorHeadless(options = {}) {
46
47
  const wrapperUrl = '/honcho-editor.js';
47
48
  // Check if wrapper script is already loaded
48
49
  if (document.querySelector(`script[src="${wrapperUrl}"]`)) {
49
- console.debug('Wrapper script already exists');
50
+ log.debug('Wrapper script already exists');
50
51
  resolve();
51
52
  return;
52
53
  }
53
- console.debug(`Loading HonchoEditor wrapper from: ${wrapperUrl}`);
54
+ log.debug({ wrapperUrl }, 'Loading HonchoEditor wrapper from URL');
54
55
  const wrapperScript = document.createElement('script');
55
56
  wrapperScript.src = wrapperUrl;
56
57
  wrapperScript.async = true;
57
58
  wrapperScript.onload = () => {
58
- console.debug('Wrapper script loaded');
59
+ log.debug('Wrapper script loaded');
59
60
  resolve();
60
61
  };
61
62
  wrapperScript.onerror = () => {
62
- console.error(`Failed to load wrapper script from: ${wrapperUrl}`);
63
+ log.error({ wrapperUrl }, 'Failed to load wrapper script from URL');
63
64
  reject(new Error('Failed to load wrapper script'));
64
65
  };
65
66
  document.head.appendChild(wrapperScript);
@@ -75,7 +76,7 @@ export function useEditorHeadless(options = {}) {
75
76
  return new Promise((resolve, reject) => {
76
77
  const checkInterval = setInterval(() => {
77
78
  if (window.HonchoEditor && typeof window.HonchoEditor === 'function') {
78
- console.debug('HonchoEditor constructor now available');
79
+ log.debug('HonchoEditor constructor now available');
79
80
  clearInterval(checkInterval);
80
81
  resolve();
81
82
  }
@@ -84,7 +85,7 @@ export function useEditorHeadless(options = {}) {
84
85
  setTimeout(() => {
85
86
  clearInterval(checkInterval);
86
87
  if (!window.HonchoEditor) {
87
- console.error('Timeout waiting for HonchoEditor constructor');
88
+ log.error('Timeout waiting for HonchoEditor constructor');
88
89
  reject(new Error('Timeout waiting for HonchoEditor constructor'));
89
90
  }
90
91
  }, 10000);
@@ -94,7 +95,7 @@ export function useEditorHeadless(options = {}) {
94
95
  setIsScriptLoaded(true);
95
96
  }
96
97
  catch (error) {
97
- console.error('Failed to load HonchoEditor scripts:', error);
98
+ log.error({ error }, 'Failed to load HonchoEditor scripts');
98
99
  setError(error instanceof Error ? error : new Error(String(error)));
99
100
  }
100
101
  };
@@ -111,7 +112,7 @@ export function useEditorHeadless(options = {}) {
111
112
  return;
112
113
  const initialize = async () => {
113
114
  try {
114
- console.debug('Script loaded, initializing editor...');
115
+ log.debug('Script loaded, initializing editor...');
115
116
  // Double-check that HonchoEditor is available
116
117
  if (!window.HonchoEditor) {
117
118
  throw new Error('window.HonchoEditor is not available');
@@ -120,24 +121,24 @@ export function useEditorHeadless(options = {}) {
120
121
  throw new Error(`window.HonchoEditor is not a constructor (type: ${typeof window.HonchoEditor})`);
121
122
  }
122
123
  if (!editorRef.current) {
123
- console.debug('Creating new HonchoEditor instance...');
124
+ log.debug('Creating new HonchoEditor instance...');
124
125
  editorRef.current = new window.HonchoEditor();
125
- console.debug('HonchoEditor instance created successfully');
126
+ log.debug('HonchoEditor instance created successfully');
126
127
  }
127
- console.debug('Initializing HonchoEditor...');
128
+ log.debug('Initializing HonchoEditor...');
128
129
  await editorRef.current.initialize(false);
129
- console.debug('HonchoEditor initialized successfully');
130
+ log.debug('HonchoEditor initialized successfully');
130
131
  setIsReady(true);
131
132
  }
132
133
  catch (e) {
133
- console.error("Failed to initialize editor:", e);
134
+ log.error({ error: e }, "Failed to initialize editor");
134
135
  setError(e instanceof Error ? e : new Error(String(e)));
135
136
  }
136
137
  };
137
138
  initialize();
138
139
  return () => {
139
140
  if (editorRef.current) {
140
- console.debug('Cleaning up HonchoEditor...');
141
+ log.debug('Cleaning up HonchoEditor...');
141
142
  editorRef.current?.cleanup();
142
143
  }
143
144
  };
@@ -148,7 +149,7 @@ export function useEditorHeadless(options = {}) {
148
149
  throw new Error('Editor not ready');
149
150
  }
150
151
  try {
151
- console.debug(`Processing image: ${task.id}`);
152
+ log.debug({ taskId: task.id }, 'Processing image');
152
153
  // Load original image as File using the new utility
153
154
  const imageFile = await loadImageAsFile(task.path);
154
155
  // Load frame if provided
@@ -165,7 +166,7 @@ export function useEditorHeadless(options = {}) {
165
166
  return { id: task.id, path: blobUrl };
166
167
  }
167
168
  catch (error) {
168
- console.error(`Failed to process image ${task.id}:`, error);
169
+ log.error({ taskId: task.id, error }, 'Failed to process image');
169
170
  throw new Error(`Failed to process image: ${error instanceof Error ? error.message : 'Unknown error'}`);
170
171
  }
171
172
  }, [isReady]);
@@ -175,25 +176,25 @@ export function useEditorHeadless(options = {}) {
175
176
  throw new Error('Editor not ready');
176
177
  }
177
178
  try {
178
- console.debug(`Loading image from URL: ${url}`);
179
+ log.debug({ url }, 'Loading image from URL');
179
180
  // First try direct load with CORS
180
181
  try {
181
182
  const size = await editorRef.current.loadImageFromUrl(url);
182
- console.debug('Image loaded successfully via direct URL');
183
+ log.debug('Image loaded successfully via direct URL');
183
184
  return size;
184
185
  }
185
186
  catch (directError) {
186
- console.warn('Direct URL load failed, trying blob approach:', directError);
187
+ log.warn({ directError }, 'Direct URL load failed, trying blob approach');
187
188
  // Fallback: Load as File using the new utility
188
189
  const imageFile = await loadImageAsFile(url);
189
190
  // Load via file method
190
191
  const size = await editorRef.current.loadImageFromFile(imageFile);
191
- console.debug('Image loaded successfully via file fallback');
192
+ log.debug('Image loaded successfully via file fallback');
192
193
  return size;
193
194
  }
194
195
  }
195
196
  catch (error) {
196
- console.error(`Failed to load image from URL ${url}:`, error);
197
+ log.error({ url, error }, 'Failed to load image from URL');
197
198
  throw new Error(`Failed to load image: ${error instanceof Error ? error.message : 'Unknown error'}`);
198
199
  }
199
200
  }, [isReady]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yogiswara/honcho-editor-ui",
3
- "version": "3.4.10",
3
+ "version": "3.4.12",
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",