funda-ui 4.7.822 → 4.7.855

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/Chatbox/index.css CHANGED
@@ -463,6 +463,16 @@
463
463
  width: 40px;
464
464
  height: 40px;
465
465
  z-index: 4;
466
+ pointer-events: all;
467
+ /* Core: Disable the system popup menu during long press */
468
+ -webkit-touch-callout: none;
469
+ /* Disable text selection */
470
+ -webkit-user-select: none;
471
+ user-select: none;
472
+ /* Core: Disable all default browser gestures to ensure touch events are passed directly to JS */
473
+ touch-action: none;
474
+ /* Remove the default tap highlight color on iOS for faster response perception */
475
+ -webkit-tap-highlight-color: transparent;
466
476
  }
467
477
  .custom-chatbox-container .msgcontrol [class*=chatbox-voice-input-btn] svg path {
468
478
  fill: var(--custom-chatbox-primary-text);
package/Chatbox/index.js CHANGED
@@ -7525,6 +7525,7 @@ var Chatbox = function Chatbox(props) {
7525
7525
  //================================================================
7526
7526
  // Voice Input
7527
7527
  //================================================================
7528
+ var pressStartTimeRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(0); // Record the time when the button was pressed.
7528
7529
  var DEFAULT_VOICE_REQUEST_BODY_TEMPLATE = "{\n \"common\": {\n \"app_id\": \"{appId}\"\n },\n \"business\": {\n \"language\": \"{lang}\",\n \"domain\": \"iat\",\n \"accent\": \"mandarin\",\n \"dwa\": \"wpgs\"\n },\n \"data\": {\n \"status\": 0,\n \"format\": \"{format}\",\n \"encoding\": \"{encoding}\"\n }\n }";
7529
7530
  var DEFAULT_AUDIO_BODY_TEMPLATE = "{\n \"data\": {\n \"status\": 1,\n \"format\": \"{format}\",\n \"encoding\": \"{encoding}\",\n \"audio\": \"{audioData}\"\n }\n }";
7530
7531
  var _useState29 = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(false),
@@ -8214,20 +8215,30 @@ var Chatbox = function Chatbox(props) {
8214
8215
  var holdToTalk = typeof (voiceConfig === null || voiceConfig === void 0 ? void 0 : voiceConfig.holdToTalk) === 'undefined' ? true : voiceConfig.holdToTalk;
8215
8216
  if (enableVoiceInput) {
8216
8217
  // Helper to stop recording safely
8217
- var handleActionStop = function handleActionStop(e) {
8218
- // Prevent firing both Mouse and Touch events on some devices
8219
- if (e.cancelable) e.preventDefault();
8220
- if (isVoiceInputActive) {
8221
- stopVoiceInput();
8222
- }
8223
- };
8224
8218
  var handleActionStart = function handleActionStart(e) {
8225
8219
  if (loading) return;
8226
8220
  if (e.cancelable) e.preventDefault();
8221
+ pressStartTimeRef.current = Date.now();
8227
8222
  if (!isVoiceInputActive) {
8228
8223
  startVoiceInput();
8229
8224
  }
8230
8225
  };
8226
+ var handleActionStop = function handleActionStop(e) {
8227
+ if (e.cancelable) e.preventDefault();
8228
+ var duration = Date.now() - pressStartTimeRef.current;
8229
+
8230
+ // If the press time is extremely short (e.g. less than 100ms),
8231
+ // it means that it is a mistakeal touch or extremely fast
8232
+ // Add a small delay to execute to ensure that startVoiceInput has finished initializing
8233
+ if (duration < 150) {
8234
+ // > 50, < 160
8235
+ setTimeout(function () {
8236
+ stopVoiceInput();
8237
+ }, 100);
8238
+ return;
8239
+ }
8240
+ stopVoiceInput();
8241
+ };
8231
8242
  return /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
8232
8243
  className: "".concat(args().prefix || 'custom-', "chatbox-voice-input-btn-wrapper ").concat(isVoiceInputActive ? 'active' : '')
8233
8244
  }, isVoiceInputActive ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("span", null) : null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("button", {
@@ -8237,18 +8248,16 @@ var Chatbox = function Chatbox(props) {
8237
8248
  userSelect: 'none'
8238
8249
  }
8239
8250
 
8240
- // Mobile
8241
- ,
8242
- onTouchStart: !holdToTalk ? undefined : handleActionStart,
8243
- onTouchEnd: !holdToTalk ? undefined : handleActionStop,
8244
- onTouchCancel: !holdToTalk ? undefined : handleActionStop // Handle system interruptions
8245
-
8246
- // Desktop
8247
- ,
8248
- onMouseDown: !holdToTalk ? undefined : handleActionStart,
8249
- onMouseUp: !holdToTalk ? undefined : handleActionStop,
8250
- onMouseLeave: !holdToTalk ? undefined : handleActionStop // Handle mouse dragging out of button
8251
+ // Mobile & Desktop
8252
+ // (using Pointer to avoid the stop problem caused by mixing Touch and Mouse)
8251
8253
  ,
8254
+ onPointerDown: holdToTalk ? handleActionStart : undefined,
8255
+ onPointerUp: holdToTalk ? handleActionStop : undefined,
8256
+ onPointerCancel: holdToTalk ? handleActionStop : undefined,
8257
+ onPointerLeave: holdToTalk ? handleActionStop : undefined,
8258
+ onContextMenu: function onContextMenu(e) {
8259
+ return e.preventDefault();
8260
+ },
8252
8261
  onClick: function onClick(e) {
8253
8262
  e.preventDefault();
8254
8263
  e.stopPropagation();
@@ -7525,6 +7525,7 @@ var Chatbox = function Chatbox(props) {
7525
7525
  //================================================================
7526
7526
  // Voice Input
7527
7527
  //================================================================
7528
+ var pressStartTimeRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(0); // Record the time when the button was pressed.
7528
7529
  var DEFAULT_VOICE_REQUEST_BODY_TEMPLATE = "{\n \"common\": {\n \"app_id\": \"{appId}\"\n },\n \"business\": {\n \"language\": \"{lang}\",\n \"domain\": \"iat\",\n \"accent\": \"mandarin\",\n \"dwa\": \"wpgs\"\n },\n \"data\": {\n \"status\": 0,\n \"format\": \"{format}\",\n \"encoding\": \"{encoding}\"\n }\n }";
7529
7530
  var DEFAULT_AUDIO_BODY_TEMPLATE = "{\n \"data\": {\n \"status\": 1,\n \"format\": \"{format}\",\n \"encoding\": \"{encoding}\",\n \"audio\": \"{audioData}\"\n }\n }";
7530
7531
  var _useState29 = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(false),
@@ -8214,20 +8215,30 @@ var Chatbox = function Chatbox(props) {
8214
8215
  var holdToTalk = typeof (voiceConfig === null || voiceConfig === void 0 ? void 0 : voiceConfig.holdToTalk) === 'undefined' ? true : voiceConfig.holdToTalk;
8215
8216
  if (enableVoiceInput) {
8216
8217
  // Helper to stop recording safely
8217
- var handleActionStop = function handleActionStop(e) {
8218
- // Prevent firing both Mouse and Touch events on some devices
8219
- if (e.cancelable) e.preventDefault();
8220
- if (isVoiceInputActive) {
8221
- stopVoiceInput();
8222
- }
8223
- };
8224
8218
  var handleActionStart = function handleActionStart(e) {
8225
8219
  if (loading) return;
8226
8220
  if (e.cancelable) e.preventDefault();
8221
+ pressStartTimeRef.current = Date.now();
8227
8222
  if (!isVoiceInputActive) {
8228
8223
  startVoiceInput();
8229
8224
  }
8230
8225
  };
8226
+ var handleActionStop = function handleActionStop(e) {
8227
+ if (e.cancelable) e.preventDefault();
8228
+ var duration = Date.now() - pressStartTimeRef.current;
8229
+
8230
+ // If the press time is extremely short (e.g. less than 100ms),
8231
+ // it means that it is a mistakeal touch or extremely fast
8232
+ // Add a small delay to execute to ensure that startVoiceInput has finished initializing
8233
+ if (duration < 150) {
8234
+ // > 50, < 160
8235
+ setTimeout(function () {
8236
+ stopVoiceInput();
8237
+ }, 100);
8238
+ return;
8239
+ }
8240
+ stopVoiceInput();
8241
+ };
8231
8242
  return /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
8232
8243
  className: "".concat(args().prefix || 'custom-', "chatbox-voice-input-btn-wrapper ").concat(isVoiceInputActive ? 'active' : '')
8233
8244
  }, isVoiceInputActive ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("span", null) : null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("button", {
@@ -8237,18 +8248,16 @@ var Chatbox = function Chatbox(props) {
8237
8248
  userSelect: 'none'
8238
8249
  }
8239
8250
 
8240
- // Mobile
8241
- ,
8242
- onTouchStart: !holdToTalk ? undefined : handleActionStart,
8243
- onTouchEnd: !holdToTalk ? undefined : handleActionStop,
8244
- onTouchCancel: !holdToTalk ? undefined : handleActionStop // Handle system interruptions
8245
-
8246
- // Desktop
8247
- ,
8248
- onMouseDown: !holdToTalk ? undefined : handleActionStart,
8249
- onMouseUp: !holdToTalk ? undefined : handleActionStop,
8250
- onMouseLeave: !holdToTalk ? undefined : handleActionStop // Handle mouse dragging out of button
8251
+ // Mobile & Desktop
8252
+ // (using Pointer to avoid the stop problem caused by mixing Touch and Mouse)
8251
8253
  ,
8254
+ onPointerDown: holdToTalk ? handleActionStart : undefined,
8255
+ onPointerUp: holdToTalk ? handleActionStop : undefined,
8256
+ onPointerCancel: holdToTalk ? handleActionStop : undefined,
8257
+ onPointerLeave: holdToTalk ? handleActionStop : undefined,
8258
+ onContextMenu: function onContextMenu(e) {
8259
+ return e.preventDefault();
8260
+ },
8252
8261
  onClick: function onClick(e) {
8253
8262
  e.preventDefault();
8254
8263
  e.stopPropagation();
@@ -463,6 +463,16 @@
463
463
  width: 40px;
464
464
  height: 40px;
465
465
  z-index: 4;
466
+ pointer-events: all;
467
+ /* Core: Disable the system popup menu during long press */
468
+ -webkit-touch-callout: none;
469
+ /* Disable text selection */
470
+ -webkit-user-select: none;
471
+ user-select: none;
472
+ /* Core: Disable all default browser gestures to ensure touch events are passed directly to JS */
473
+ touch-action: none;
474
+ /* Remove the default tap highlight color on iOS for faster response perception */
475
+ -webkit-tap-highlight-color: transparent;
466
476
  }
467
477
  .custom-chatbox-container .msgcontrol [class*=chatbox-voice-input-btn] svg path {
468
478
  fill: var(--custom-chatbox-primary-text);
@@ -560,6 +560,20 @@
560
560
  width: 40px;
561
561
  height: 40px;
562
562
  z-index: 4;
563
+ pointer-events: all;
564
+
565
+ /* Core: Disable the system popup menu during long press */
566
+ -webkit-touch-callout: none;
567
+
568
+ /* Disable text selection */
569
+ -webkit-user-select: none;
570
+ user-select: none;
571
+
572
+ /* Core: Disable all default browser gestures to ensure touch events are passed directly to JS */
573
+ touch-action: none;
574
+
575
+ /* Remove the default tap highlight color on iOS for faster response perception */
576
+ -webkit-tap-highlight-color: transparent;
563
577
 
564
578
  svg path {
565
579
  fill: var(--custom-chatbox-primary-text);
@@ -1380,6 +1380,7 @@ const Chatbox = (props: ChatboxProps) => {
1380
1380
  //================================================================
1381
1381
  // Voice Input
1382
1382
  //================================================================
1383
+ const pressStartTimeRef = useRef<number>(0); // Record the time when the button was pressed.
1383
1384
  const DEFAULT_VOICE_REQUEST_BODY_TEMPLATE = `{
1384
1385
  "common": {
1385
1386
  "app_id": "{appId}"
@@ -1730,6 +1731,7 @@ const Chatbox = (props: ChatboxProps) => {
1730
1731
  console.error('--> The voice input failed to start:', error);
1731
1732
  config.onVoiceInputError?.(error as Error);
1732
1733
  }
1734
+
1733
1735
  };
1734
1736
 
1735
1737
  const stopVoiceInput = async () => {
@@ -2065,24 +2067,36 @@ const Chatbox = (props: ChatboxProps) => {
2065
2067
  if (enableVoiceInput) {
2066
2068
 
2067
2069
  // Helper to stop recording safely
2068
- const handleActionStop = (e: React.SyntheticEvent) => {
2069
- // Prevent firing both Mouse and Touch events on some devices
2070
- if (e.cancelable) e.preventDefault();
2071
-
2072
- if (isVoiceInputActive) {
2073
- stopVoiceInput();
2074
- }
2075
- };
2076
-
2077
2070
  const handleActionStart = (e: React.SyntheticEvent) => {
2078
2071
  if (loading) return;
2079
2072
  if (e.cancelable) e.preventDefault();
2080
-
2073
+
2074
+ pressStartTimeRef.current = Date.now();
2075
+
2081
2076
  if (!isVoiceInputActive) {
2082
2077
  startVoiceInput();
2083
2078
  }
2084
2079
  };
2085
2080
 
2081
+ const handleActionStop = (e: React.SyntheticEvent) => {
2082
+ if (e.cancelable) e.preventDefault();
2083
+
2084
+ const duration = Date.now() - pressStartTimeRef.current;
2085
+
2086
+ // If the press time is extremely short (e.g. less than 100ms),
2087
+ // it means that it is a mistakeal touch or extremely fast
2088
+ // Add a small delay to execute to ensure that startVoiceInput has finished initializing
2089
+ if (duration < 150) { // > 50, < 160
2090
+ setTimeout(() => {
2091
+ stopVoiceInput();
2092
+ }, 100);
2093
+ return;
2094
+ }
2095
+
2096
+ stopVoiceInput();
2097
+
2098
+ };
2099
+
2086
2100
  return (
2087
2101
  <div className={`${args().prefix || 'custom-'}chatbox-voice-input-btn-wrapper ${isVoiceInputActive ? 'active' : ''}`}>
2088
2102
  {isVoiceInputActive ? <span></span> : null}
@@ -2090,15 +2104,13 @@ const Chatbox = (props: ChatboxProps) => {
2090
2104
  // CSS touch-action is crucial here
2091
2105
  style={!holdToTalk ? undefined : { touchAction: 'none', userSelect: 'none' }}
2092
2106
 
2093
- // Mobile
2094
- onTouchStart={!holdToTalk ? undefined : handleActionStart}
2095
- onTouchEnd={!holdToTalk ? undefined : handleActionStop}
2096
- onTouchCancel={!holdToTalk ? undefined : handleActionStop} // Handle system interruptions
2097
-
2098
- // Desktop
2099
- onMouseDown={!holdToTalk ? undefined : handleActionStart}
2100
- onMouseUp={!holdToTalk ? undefined : handleActionStop}
2101
- onMouseLeave={!holdToTalk ? undefined : handleActionStop} // Handle mouse dragging out of button
2107
+ // Mobile & Desktop
2108
+ // (using Pointer to avoid the stop problem caused by mixing Touch and Mouse)
2109
+ onPointerDown={holdToTalk ? handleActionStart : undefined}
2110
+ onPointerUp={holdToTalk ? handleActionStop : undefined}
2111
+ onPointerCancel={holdToTalk ? handleActionStop : undefined}
2112
+ onPointerLeave={holdToTalk ? handleActionStop : undefined}
2113
+ onContextMenu={(e) => e.preventDefault()}
2102
2114
  onClick={(e: React.MouseEvent) => {
2103
2115
  e.preventDefault();
2104
2116
  e.stopPropagation();
@@ -171,7 +171,7 @@ export function extractHtmlTags(html: string): { processedHtml: string; placehol
171
171
  };
172
172
 
173
173
 
174
- export function toBoolean(val) {
174
+ export function toBoolean(val: any) {
175
175
  if (typeof val === "boolean") return val;
176
176
  if (typeof val === "string") {
177
177
  return val.toLowerCase() === "true";
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.822","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}
1
+ {"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.855","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}