@apteva/apteva-kit 0.1.114 → 0.1.116

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/dist/index.js CHANGED
@@ -1449,9 +1449,12 @@ function PortalDropdown({
1449
1449
  children
1450
1450
  }) {
1451
1451
  const dropdownRef = _react.useRef.call(void 0, null);
1452
- const [pos, setPos] = _react.useState.call(void 0, { top: 0, left: 0, width: 0 });
1452
+ const [pos, setPos] = _react.useState.call(void 0, null);
1453
1453
  _react.useEffect.call(void 0, () => {
1454
- if (!open || !anchorRef.current) return;
1454
+ if (!open || !anchorRef.current) {
1455
+ setPos(null);
1456
+ return;
1457
+ }
1455
1458
  const update = () => {
1456
1459
  const rect = anchorRef.current.getBoundingClientRect();
1457
1460
  setPos({
@@ -1487,7 +1490,7 @@ function PortalDropdown({
1487
1490
  document.addEventListener("keydown", handler);
1488
1491
  return () => document.removeEventListener("keydown", handler);
1489
1492
  }, [open, onClose]);
1490
- if (!open) return null;
1493
+ if (!open || !pos) return null;
1491
1494
  return _reactdom.createPortal.call(void 0,
1492
1495
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1493
1496
  "div",
@@ -1517,7 +1520,7 @@ function CustomSelect({
1517
1520
  }) {
1518
1521
  const [open, setOpen] = _react.useState.call(void 0, false);
1519
1522
  const triggerRef = _react.useRef.call(void 0, null);
1520
- const selected = _optionalChain([options, 'optionalAccess', _18 => _18.find, 'call', _19 => _19((o) => o.value === value)]);
1523
+ const selected = _optionalChain([options, 'optionalAccess', _18 => _18.find, 'call', _19 => _19((o) => o.label === value || o.value === value)]);
1521
1524
  const close = _react.useCallback.call(void 0, () => setOpen(false), []);
1522
1525
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "apteva-select relative", children: [
1523
1526
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -1533,7 +1536,7 @@ function CustomSelect({
1533
1536
  "aria-hidden": true,
1534
1537
  children: [
1535
1538
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: "" }),
1536
- _optionalChain([options, 'optionalAccess', _20 => _20.map, 'call', _21 => _21((o) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: o.value, children: o.label }, o.value))])
1539
+ _optionalChain([options, 'optionalAccess', _20 => _20.map, 'call', _21 => _21((o) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: o.label, children: o.label }, o.value))])
1537
1540
  ]
1538
1541
  }
1539
1542
  ),
@@ -1565,10 +1568,10 @@ function CustomSelect({
1565
1568
  {
1566
1569
  type: "button",
1567
1570
  onClick: () => {
1568
- onChange(opt.value);
1571
+ onChange(opt.label);
1569
1572
  close();
1570
1573
  },
1571
- className: `apteva-select-option w-full text-left px-3 py-2 text-sm transition-colors ${opt.value === value ? "apteva-select-option-active" : ""}`,
1574
+ className: `apteva-select-option w-full text-left px-3 py-2 text-sm transition-colors ${value === opt.label ? "apteva-select-option-active" : ""}`,
1572
1575
  children: opt.label
1573
1576
  },
1574
1577
  opt.value
@@ -3373,41 +3376,56 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3373
3376
  stopRecording(true);
3374
3377
  };
3375
3378
  }, []);
3376
- const drawWaveform = _react.useCallback.call(void 0, () => {
3379
+ const startWaveformLoop = _react.useCallback.call(void 0, () => {
3377
3380
  const canvas = canvasRef.current;
3378
3381
  const analyser = analyserRef.current;
3379
3382
  if (!canvas || !analyser) return;
3383
+ const dpr = window.devicePixelRatio || 1;
3384
+ const rect = canvas.getBoundingClientRect();
3385
+ canvas.width = rect.width * dpr;
3386
+ canvas.height = rect.height * dpr;
3380
3387
  const ctx = canvas.getContext("2d");
3381
3388
  if (!ctx) return;
3389
+ ctx.scale(dpr, dpr);
3382
3390
  const bufferLength = analyser.frequencyBinCount;
3383
3391
  const dataArray = new Uint8Array(bufferLength);
3392
+ const smoothed = new Float32Array(40).fill(2);
3384
3393
  const draw = () => {
3385
3394
  animFrameRef.current = requestAnimationFrame(draw);
3386
3395
  analyser.getByteTimeDomainData(dataArray);
3387
- const { width, height } = canvas;
3388
- ctx.clearRect(0, 0, width, height);
3389
- const barCount = 32;
3390
- const barWidth = Math.max(2, (width - (barCount - 1) * 2) / barCount);
3396
+ const w = rect.width;
3397
+ const h = rect.height;
3398
+ ctx.clearRect(0, 0, w, h);
3399
+ const barCount = 40;
3391
3400
  const gap = 2;
3401
+ const barWidth = Math.max(2, (w - (barCount - 1) * gap) / barCount);
3392
3402
  const samplesPerBar = Math.floor(bufferLength / barCount);
3393
3403
  for (let i = 0; i < barCount; i++) {
3394
- let sum = 0;
3404
+ let sumSq = 0;
3395
3405
  for (let j = 0; j < samplesPerBar; j++) {
3396
- const val = dataArray[i * samplesPerBar + j] - 128;
3397
- sum += Math.abs(val);
3406
+ const val = (dataArray[i * samplesPerBar + j] - 128) / 128;
3407
+ sumSq += val * val;
3398
3408
  }
3399
- const avg = sum / samplesPerBar;
3400
- const barHeight = Math.max(3, avg / 128 * height * 2.5);
3409
+ const rms = Math.sqrt(sumSq / samplesPerBar);
3410
+ const target = Math.max(2, rms * h * 3);
3411
+ smoothed[i] += (target - smoothed[i]) * (target > smoothed[i] ? 0.4 : 0.15);
3412
+ const barHeight = Math.min(smoothed[i], h - 2);
3401
3413
  const x = i * (barWidth + gap);
3402
- const y = (height - barHeight) / 2;
3414
+ const y = (h - barHeight) / 2;
3415
+ const radius = Math.min(barWidth / 2, barHeight / 2);
3403
3416
  ctx.fillStyle = "#3b82f6";
3404
3417
  ctx.beginPath();
3405
- ctx.roundRect(x, y, barWidth, barHeight, barWidth / 2);
3418
+ ctx.roundRect(x, y, barWidth, barHeight, radius);
3406
3419
  ctx.fill();
3407
3420
  }
3408
3421
  };
3409
3422
  draw();
3410
3423
  }, []);
3424
+ _react.useEffect.call(void 0, () => {
3425
+ if (isRecording && canvasRef.current && analyserRef.current) {
3426
+ startWaveformLoop();
3427
+ }
3428
+ }, [isRecording, startWaveformLoop]);
3411
3429
  const startRecording = _react.useCallback.call(void 0, async () => {
3412
3430
  const SpeechRecognitionCtor = getSpeechRecognition();
3413
3431
  if (!SpeechRecognitionCtor) return;
@@ -3464,7 +3482,6 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3464
3482
  recordingTimerRef.current = setInterval(() => {
3465
3483
  setRecordingTime((t) => t + 1);
3466
3484
  }, 1e3);
3467
- requestAnimationFrame(() => drawWaveform());
3468
3485
  silenceTimerRef.current = setTimeout(() => {
3469
3486
  stopRecording(false);
3470
3487
  }, silenceTimeout + 1e3);
@@ -3473,7 +3490,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3473
3490
  setFileError("Microphone access denied");
3474
3491
  setTimeout(() => setFileError(null), 3e3);
3475
3492
  }
3476
- }, [_optionalChain([sttConfig, 'optionalAccess', _57 => _57.language]), silenceTimeout, drawWaveform]);
3493
+ }, [_optionalChain([sttConfig, 'optionalAccess', _57 => _57.language]), silenceTimeout]);
3477
3494
  const finishRecording = _react.useCallback.call(void 0, () => {
3478
3495
  const transcript = finalTranscriptRef.current.trim();
3479
3496
  setIsRecording(false);
@@ -3650,10 +3667,10 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3650
3667
  style: {
3651
3668
  gridTemplateColumns: isRecording ? gridColsRecording : gridCols,
3652
3669
  gridTemplateAreas: isRecording ? '"plus waveform stop"' : gridAreas,
3653
- alignItems: "end"
3670
+ alignItems: isRecording ? "center" : "end"
3654
3671
  },
3655
3672
  children: [
3656
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex-shrink-0 self-end", style: { gridArea: "plus" }, children: isRecording ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-composer-rec-dot", title: "Recording...", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3673
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex-shrink-0", style: { gridArea: "plus", alignSelf: isRecording ? "center" : "end" }, children: isRecording ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-composer-rec-dot", title: "Recording...", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3657
3674
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3658
3675
  "button",
3659
3676
  {
@@ -3714,14 +3731,12 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3714
3731
  "canvas",
3715
3732
  {
3716
3733
  ref: canvasRef,
3717
- width: 300,
3718
- height: 36,
3719
3734
  className: "apteva-composer-waveform-canvas"
3720
3735
  }
3721
3736
  ),
3722
3737
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-composer-recording-timer", children: formatTime(recordingTime) })
3723
3738
  ] }),
3724
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "self-end", style: { gridArea: "stop" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3739
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "self-center", style: { gridArea: "stop" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3725
3740
  "button",
3726
3741
  {
3727
3742
  onClick: () => stopRecording(false),