@skippr/live-agent-sdk 0.117.0 → 0.119.0

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.
@@ -6169,11 +6169,11 @@ function barPopsDown(pos) {
6169
6169
  function barLeftAligned(pos) {
6170
6170
  return pos.x + VOICE_BAR_WIDTH_PX / 2 < window.innerWidth / 2;
6171
6171
  }
6172
- function defaultBarPos() {
6172
+ function defaultBarPos(widthPx) {
6173
6173
  return clampBarPos({
6174
- x: window.innerWidth / 2 - VOICE_BAR_WIDTH_PX / 2,
6174
+ x: window.innerWidth / 2 - widthPx / 2,
6175
6175
  y: window.innerHeight - VOICE_BAR_EDGE_MARGIN_PX - VOICE_BAR_HEIGHT_PX
6176
- }, VOICE_BAR_WIDTH_PX);
6176
+ }, widthPx);
6177
6177
  }
6178
6178
  function barPosStyle(pos) {
6179
6179
  return {
@@ -10605,7 +10605,7 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
10605
10605
  return /* @__PURE__ */ jsxs24("form", {
10606
10606
  onSubmit: handleSubmit,
10607
10607
  "data-skippr-no-drag": "",
10608
- className: "skippr:flex skippr:items-center skippr:gap-[7px] skippr:border-t skippr:border-[rgba(45,45,63,0.08)] skippr:bg-white skippr:p-[9px]",
10608
+ className: "skippr:flex skippr:shrink-0 skippr:items-center skippr:gap-[7px] skippr:border-t skippr:border-[rgba(45,45,63,0.08)] skippr:bg-white skippr:p-[9px]",
10609
10609
  children: [
10610
10610
  /* @__PURE__ */ jsx31("textarea", {
10611
10611
  ref: textareaRef,
@@ -10738,17 +10738,20 @@ function LinkCard({ card, onDismiss }) {
10738
10738
  href: card.url,
10739
10739
  target: "_blank",
10740
10740
  rel: "noopener noreferrer",
10741
- className: "skippr:inline-flex skippr:flex-1 skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-md skippr:bg-primary skippr:py-2 skippr:text-sm skippr:font-medium skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90 skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-ring skippr:focus-visible:ring-offset-2",
10741
+ className: "skippr:inline-flex skippr:min-w-0 skippr:flex-1 skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-md skippr:bg-primary skippr:py-2 skippr:text-xs skippr:font-medium skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90 skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-ring skippr:focus-visible:ring-offset-2",
10742
10742
  children: [
10743
10743
  /* @__PURE__ */ jsx33(ExternalLink, {
10744
- className: "skippr:size-4"
10744
+ className: "skippr:size-4 skippr:shrink-0"
10745
10745
  }),
10746
- copy.cardOpenLink
10746
+ /* @__PURE__ */ jsx33("span", {
10747
+ className: "skippr:truncate",
10748
+ children: copy.cardOpenLink
10749
+ })
10747
10750
  ]
10748
10751
  }),
10749
10752
  /* @__PURE__ */ jsxs26(Button, {
10750
10753
  variant: "outline",
10751
- className: "skippr:flex-1 skippr:py-2",
10754
+ className: "skippr:px-2 skippr:py-2 skippr:text-xs",
10752
10755
  onClick: handleCopy,
10753
10756
  "aria-label": copy.cardCopyLink,
10754
10757
  children: [
@@ -10776,21 +10779,21 @@ var APPROVING_RESET_MS = 8000;
10776
10779
  function StepIcon({ status }) {
10777
10780
  if (status === "done") {
10778
10781
  return /* @__PURE__ */ jsx34(CircleCheck, {
10779
- className: "skippr:size-4 skippr:text-chart-3"
10782
+ className: "skippr:size-4 skippr:shrink-0 skippr:text-chart-3"
10780
10783
  });
10781
10784
  }
10782
10785
  if (status === "failed") {
10783
10786
  return /* @__PURE__ */ jsx34(CircleX, {
10784
- className: "skippr:size-4 skippr:text-destructive"
10787
+ className: "skippr:size-4 skippr:shrink-0 skippr:text-destructive"
10785
10788
  });
10786
10789
  }
10787
10790
  if (status === "active") {
10788
10791
  return /* @__PURE__ */ jsx34(Circle, {
10789
- className: "skippr:size-4 skippr:fill-primary/30 skippr:text-primary"
10792
+ className: "skippr:size-4 skippr:shrink-0 skippr:fill-primary/30 skippr:text-primary"
10790
10793
  });
10791
10794
  }
10792
10795
  return /* @__PURE__ */ jsx34(Circle, {
10793
- className: "skippr:size-4 skippr:text-muted-foreground/30"
10796
+ className: "skippr:size-4 skippr:shrink-0 skippr:text-muted-foreground/30"
10794
10797
  });
10795
10798
  }
10796
10799
  function PlanCard({ plan, sendChatMessage, onDismiss }) {
@@ -10822,14 +10825,14 @@ function PlanCard({ plan, sendChatMessage, onDismiss }) {
10822
10825
  return () => clearTimeout(timer);
10823
10826
  }, [plan.state, onDismiss]);
10824
10827
  return /* @__PURE__ */ jsxs27("div", {
10825
- className: "skippr:rounded-2xl skippr:rounded-tl-md skippr:bg-card skippr:p-3.5 skippr:ring-2 skippr:ring-brand",
10828
+ className: "skippr:flex skippr:min-h-0 skippr:min-w-0 skippr:flex-1 skippr:flex-col skippr:rounded-2xl skippr:rounded-tl-md skippr:bg-card skippr:p-3.5 skippr:ring-2 skippr:ring-brand",
10826
10829
  children: [
10827
10830
  /* @__PURE__ */ jsx34("p", {
10828
- className: "skippr:mb-3 skippr:text-xs skippr:font-semibold skippr:leading-snug skippr:text-foreground",
10831
+ className: "skippr:mb-3 skippr:shrink-0 skippr:text-xs skippr:font-semibold skippr:leading-snug skippr:text-foreground",
10829
10832
  children: copy.planTitle
10830
10833
  }),
10831
10834
  /* @__PURE__ */ jsx34("div", {
10832
- className: "skippr:max-h-[132px] skippr:space-y-2 skippr:overflow-y-auto skippr:overscroll-contain",
10835
+ className: "skippr:min-h-0 skippr:max-h-[132px] skippr:space-y-2 skippr:overflow-y-auto skippr:overscroll-contain",
10833
10836
  children: plan.steps.map((step) => /* @__PURE__ */ jsxs27("div", {
10834
10837
  className: "skippr:flex skippr:items-center skippr:gap-2",
10835
10838
  children: [
@@ -10844,22 +10847,25 @@ function PlanCard({ plan, sendChatMessage, onDismiss }) {
10844
10847
  }, step.index))
10845
10848
  }),
10846
10849
  awaitingApproval && /* @__PURE__ */ jsxs27("div", {
10847
- className: "skippr:mt-3.5 skippr:flex skippr:gap-2",
10850
+ className: "skippr:mt-3.5 skippr:flex skippr:shrink-0 skippr:gap-2",
10848
10851
  children: [
10849
10852
  /* @__PURE__ */ jsxs27(Button, {
10850
- className: "skippr:flex-1 skippr:gap-1.5 skippr:py-2",
10853
+ className: "skippr:min-w-0 skippr:flex-1 skippr:gap-1.5 skippr:px-3 skippr:py-2 skippr:text-xs",
10851
10854
  disabled: isApproving,
10852
10855
  onClick: approve,
10853
10856
  children: [
10854
10857
  isApproving && /* @__PURE__ */ jsx34("span", {
10855
10858
  className: "skippr:size-3 skippr:shrink-0 skippr:animate-spin skippr:rounded-full skippr:border-2 skippr:border-white/30 skippr:border-t-white"
10856
10859
  }),
10857
- isApproving ? copy.planApproving : copy.planApprove
10860
+ /* @__PURE__ */ jsx34("span", {
10861
+ className: "skippr:truncate",
10862
+ children: isApproving ? copy.planApproving : copy.planApprove
10863
+ })
10858
10864
  ]
10859
10865
  }),
10860
10866
  /* @__PURE__ */ jsx34(Button, {
10861
10867
  variant: "outline",
10862
- className: "skippr:flex-1 skippr:py-2",
10868
+ className: "skippr:px-3 skippr:py-2 skippr:text-xs",
10863
10869
  disabled: isApproving,
10864
10870
  onClick: () => sendChatMessage(CANCEL_MESSAGE),
10865
10871
  children: copy.planCancel
@@ -11000,7 +11006,7 @@ function MessageList({
11000
11006
  }),
11001
11007
  isPlanShowing && /* @__PURE__ */ jsx36("div", {
11002
11008
  "data-skippr-no-drag": "",
11003
- className: "skippr:shrink-0 skippr:border-t skippr:border-border skippr:p-3",
11009
+ className: "skippr:flex skippr:min-h-0 skippr:border-t skippr:border-border skippr:p-3",
11004
11010
  children: /* @__PURE__ */ jsx36(PlanCard, {
11005
11011
  plan,
11006
11012
  sendChatMessage,
@@ -12581,7 +12587,7 @@ function useBarNotifications() {
12581
12587
 
12582
12588
  // src/components/VoiceBarFrame.tsx
12583
12589
  import { useIsSpeaking, useLocalParticipant as useLocalParticipant13 } from "@livekit/components-react/hooks";
12584
- import { useCallback as useCallback34, useContext as useContext27, useEffect as useEffect48, useRef as useRef43, useState as useState39 } from "react";
12590
+ import { useCallback as useCallback34, useContext as useContext27, useEffect as useEffect48, useLayoutEffect as useLayoutEffect5, useRef as useRef43, useState as useState39 } from "react";
12585
12591
 
12586
12592
  // src/hooks/useKeyboardStop.ts
12587
12593
  import { useEffect as useEffect40, useRef as useRef37 } from "react";
@@ -13582,8 +13588,15 @@ function VoiceBarFrame({
13582
13588
  const showLivePill = !isLoading && isConnected && !textMode && !pushOrTap;
13583
13589
  const barWidthPx = !showLivePill ? VOICE_BAR_WIDTH_PX : isHeld ? 120 : 156;
13584
13590
  barWidthRef.current = barWidthPx;
13585
- useEffect48(() => {
13586
- const inBounds = clampBarPos(pos, barWidthPx);
13591
+ const effectivePos = pos ?? defaultBarPos(barWidthPx);
13592
+ const posWidthRef = useRef43(barWidthPx);
13593
+ useLayoutEffect5(() => {
13594
+ const prevWidthPx = posWidthRef.current;
13595
+ posWidthRef.current = barWidthPx;
13596
+ if (pos === null)
13597
+ return;
13598
+ const centered = prevWidthPx === barWidthPx ? pos : { x: pos.x + Math.trunc((prevWidthPx - barWidthPx) / 2), y: pos.y };
13599
+ const inBounds = clampBarPos(centered, barWidthPx);
13587
13600
  if (inBounds.x !== pos.x)
13588
13601
  onDrop(inBounds, barWidthPx);
13589
13602
  }, [pos, barWidthPx, onDrop]);
@@ -13668,8 +13681,8 @@ function VoiceBarFrame({
13668
13681
  const showAutoOffStrip = !slotClaimed && autoOffClosing;
13669
13682
  const hintSuppressed = slotClaimed || isCapturingSpeech || planCardActive || showLiveStrip || isHeld || showTimerStrip || showAutoOffStrip;
13670
13683
  const liveStripLabel = showActionControl ? copy.voiceBarWorking : copy.voiceBarThinking;
13671
- const popsDown = barPopsDown(pos);
13672
- const isLeftAligned = barLeftAligned(pos);
13684
+ const popsDown = barPopsDown(effectivePos);
13685
+ const isLeftAligned = barLeftAligned(effectivePos);
13673
13686
  const stripStyle = {
13674
13687
  position: "absolute",
13675
13688
  left: 0,
@@ -13691,7 +13704,7 @@ function VoiceBarFrame({
13691
13704
  const pillEvaporate = autoOffClosing ? "skippr:[animation:skippr-evaporate_3.2s_ease-in_forwards] skippr:motion-reduce:animate-none" : "";
13692
13705
  return /* @__PURE__ */ jsxs41("div", {
13693
13706
  ref: setContainerRefs,
13694
- style: { ...barPosStyle(pos), width: barWidthPx },
13707
+ style: { ...barPosStyle(effectivePos), width: barWidthPx },
13695
13708
  className: "skippr:fixed skippr:z-[9999] skippr:flex skippr:touch-none skippr:cursor-grab skippr:items-center",
13696
13709
  children: [
13697
13710
  glow && /* @__PURE__ */ jsx52("span", {
@@ -13842,7 +13855,7 @@ function VoiceBarFrame({
13842
13855
  }),
13843
13856
  bannerActive && !chatOpen && !isCapturingSpeech && !planCardActive && /* @__PURE__ */ jsx52(VoiceBarNotification, {
13844
13857
  notifications,
13845
- pos,
13858
+ pos: effectivePos,
13846
13859
  onDismiss: closeBanner
13847
13860
  }),
13848
13861
  /* @__PURE__ */ jsxs41("div", {
@@ -14542,9 +14555,8 @@ function VoiceBar({ revealed }) {
14542
14555
  if (isPanelOpen && splashSurfaces.panel) {
14543
14556
  return null;
14544
14557
  }
14545
- const effectiveBarPos = barPos ?? defaultBarPos();
14546
14558
  return /* @__PURE__ */ jsx55(VoiceBarFrame, {
14547
- pos: effectiveBarPos,
14559
+ pos: barPos,
14548
14560
  canFold,
14549
14561
  notifications,
14550
14562
  onDrop: setBarPos,
@@ -14916,7 +14928,7 @@ function LiveAgent(props) {
14916
14928
  const syncBarToViewport = () => {
14917
14929
  const ratios = barPosRatioRef.current;
14918
14930
  const measured = voiceBarRef.current?.getBoundingClientRect().width;
14919
- setBarPosState(ratios === null ? defaultBarPos() : clampBarPos({
14931
+ setBarPosState(ratios === null ? null : clampBarPos({
14920
14932
  x: ratios.xRatio * window.innerWidth,
14921
14933
  y: ratios.yRatio * window.innerHeight
14922
14934
  }, measured || VOICE_BAR_WIDTH_PX));