@epicbagel/saas-kit 1.10.0 → 1.11.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.
Files changed (43) hide show
  1. package/README.md +15 -4
  2. package/dist/{chunk-VBKJXNEL.js → chunk-5OF6D3GH.js} +4 -3
  3. package/dist/{chunk-UW67GSZ4.cjs → chunk-7QTFYEPE.cjs} +51 -25
  4. package/dist/{chunk-M2ZNC3TK.js → chunk-HLAHOVEI.js} +98 -2
  5. package/dist/chunk-KQBXAQAY.cjs +221 -0
  6. package/dist/{chunk-XB2D4NQK.cjs → chunk-NKWHDI4C.cjs} +4 -3
  7. package/dist/chunk-T3XMHWYV.js +221 -0
  8. package/dist/chunk-UOVA4YKW.js +153 -0
  9. package/dist/{chunk-O6F3LVZY.cjs → chunk-ZZ7ICQR2.cjs} +120 -24
  10. package/dist/hooks/use-dictation.cjs +2 -2
  11. package/dist/hooks/use-dictation.d.cts +5 -0
  12. package/dist/hooks/use-dictation.d.ts +5 -0
  13. package/dist/hooks/use-dictation.js +1 -1
  14. package/dist/primitives/agent-audio-visualizer-bar.cjs +2 -2
  15. package/dist/primitives/agent-audio-visualizer-bar.d.cts +1 -1
  16. package/dist/primitives/agent-audio-visualizer-bar.d.ts +1 -1
  17. package/dist/primitives/agent-audio-visualizer-bar.js +1 -1
  18. package/dist/primitives/alert.d.cts +1 -1
  19. package/dist/primitives/alert.d.ts +1 -1
  20. package/dist/primitives/badge.d.cts +1 -1
  21. package/dist/primitives/badge.d.ts +1 -1
  22. package/dist/primitives/bubble.d.cts +1 -1
  23. package/dist/primitives/bubble.d.ts +1 -1
  24. package/dist/primitives/button.d.cts +2 -2
  25. package/dist/primitives/button.d.ts +2 -2
  26. package/dist/primitives/chat.cjs +15 -15
  27. package/dist/primitives/chat.d.cts +2 -2
  28. package/dist/primitives/chat.d.ts +2 -2
  29. package/dist/primitives/chat.js +10 -10
  30. package/dist/primitives/dictation-provider.cjs +2 -2
  31. package/dist/primitives/dictation-provider.js +1 -1
  32. package/dist/primitives/voice-dictation-button.cjs +5 -3
  33. package/dist/primitives/voice-dictation-button.d.cts +5 -9
  34. package/dist/primitives/voice-dictation-button.d.ts +5 -9
  35. package/dist/primitives/voice-dictation-button.js +4 -2
  36. package/dist/primitives/voice-session-controls.cjs +3 -3
  37. package/dist/primitives/voice-session-controls.d.cts +4 -2
  38. package/dist/primitives/voice-session-controls.d.ts +4 -2
  39. package/dist/primitives/voice-session-controls.js +2 -2
  40. package/package.json +1 -1
  41. package/dist/chunk-HTCW6AEH.cjs +0 -223
  42. package/dist/chunk-KUG4ONYC.js +0 -127
  43. package/dist/chunk-KWV5KTOA.js +0 -223
@@ -3,8 +3,8 @@
3
3
 
4
4
 
5
5
 
6
- var _chunkO6F3LVZYcjs = require('../chunk-O6F3LVZY.cjs');
6
+ var _chunkZZ7ICQR2cjs = require('../chunk-ZZ7ICQR2.cjs');
7
7
 
8
8
 
9
9
 
10
- exports.DictationProvider = _chunkO6F3LVZYcjs.DictationProvider; exports.useDictation = _chunkO6F3LVZYcjs.useDictation;
10
+ exports.DictationProvider = _chunkZZ7ICQR2cjs.DictationProvider; exports.useDictation = _chunkZZ7ICQR2cjs.useDictation;
@@ -43,6 +43,11 @@ interface DictationCapture {
43
43
  interimTranscript: string;
44
44
  error: string | null;
45
45
  canRetry: boolean;
46
+ /** Live bands from the recording stream. Native speech recognition exposes no audio meter. */
47
+ audioLevels?: {
48
+ subscribe: (listener: () => void) => () => void;
49
+ getSnapshot: () => number[];
50
+ };
46
51
  start: () => Promise<void>;
47
52
  /** Returns null on cancellation/failure; concurrent stops share one transcription. */
48
53
  stop: () => Promise<string | null>;
@@ -43,6 +43,11 @@ interface DictationCapture {
43
43
  interimTranscript: string;
44
44
  error: string | null;
45
45
  canRetry: boolean;
46
+ /** Live bands from the recording stream. Native speech recognition exposes no audio meter. */
47
+ audioLevels?: {
48
+ subscribe: (listener: () => void) => () => void;
49
+ getSnapshot: () => number[];
50
+ };
46
51
  start: () => Promise<void>;
47
52
  /** Returns null on cancellation/failure; concurrent stops share one transcription. */
48
53
  stop: () => Promise<string | null>;
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  DictationProvider,
5
5
  useDictation
6
- } from "../chunk-M2ZNC3TK.js";
6
+ } from "../chunk-HLAHOVEI.js";
7
7
  export {
8
8
  DictationProvider,
9
9
  useDictation
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
 
8
- var _chunkXB2D4NQKcjs = require('../chunk-XB2D4NQK.cjs');
8
+ var _chunkNKWHDI4Ccjs = require('../chunk-NKWHDI4C.cjs');
9
9
  require('../chunk-KWLSBTB2.cjs');
10
10
  require('../chunk-2BSFYU22.cjs');
11
11
 
@@ -13,4 +13,4 @@ require('../chunk-2BSFYU22.cjs');
13
13
 
14
14
 
15
15
 
16
- exports.AgentAudioVisualizerBar = _chunkXB2D4NQKcjs.AgentAudioVisualizerBar; exports.AgentAudioVisualizerBarElementVariants = _chunkXB2D4NQKcjs.AgentAudioVisualizerBarElementVariants; exports.AgentAudioVisualizerBarVariants = _chunkXB2D4NQKcjs.AgentAudioVisualizerBarVariants; exports.normalizeVolumeBands = _chunkXB2D4NQKcjs.normalizeVolumeBands;
16
+ exports.AgentAudioVisualizerBar = _chunkNKWHDI4Ccjs.AgentAudioVisualizerBar; exports.AgentAudioVisualizerBarElementVariants = _chunkNKWHDI4Ccjs.AgentAudioVisualizerBarElementVariants; exports.AgentAudioVisualizerBarVariants = _chunkNKWHDI4Ccjs.AgentAudioVisualizerBarVariants; exports.normalizeVolumeBands = _chunkNKWHDI4Ccjs.normalizeVolumeBands;
@@ -57,7 +57,7 @@ interface AgentAudioVisualizerBarProps {
57
57
  /**
58
58
  * A bar-style audio visualizer that responds to agent state and audio levels.
59
59
  * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)
60
- * and audio volume when speaking.
60
+ * and audio volume when speaking or listening with supplied microphone bands.
61
61
  *
62
62
  * @extends ComponentProps<'div'>
63
63
  *
@@ -57,7 +57,7 @@ interface AgentAudioVisualizerBarProps {
57
57
  /**
58
58
  * A bar-style audio visualizer that responds to agent state and audio levels.
59
59
  * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)
60
- * and audio volume when speaking.
60
+ * and audio volume when speaking or listening with supplied microphone bands.
61
61
  *
62
62
  * @extends ComponentProps<'div'>
63
63
  *
@@ -5,7 +5,7 @@ import {
5
5
  AgentAudioVisualizerBarElementVariants,
6
6
  AgentAudioVisualizerBarVariants,
7
7
  normalizeVolumeBands
8
- } from "../chunk-VBKJXNEL.js";
8
+ } from "../chunk-5OF6D3GH.js";
9
9
  import "../chunk-G6SRSWXB.js";
10
10
  import "../chunk-GJ7S3L6R.js";
11
11
  export {
@@ -4,7 +4,7 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const alertVariants: (props?: ({
7
- variant?: "success" | "default" | "destructive" | "warning" | null | undefined;
7
+ variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface AlertProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {
10
10
  marginBottom?: "none" | "md";
@@ -4,7 +4,7 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const alertVariants: (props?: ({
7
- variant?: "success" | "default" | "destructive" | "warning" | null | undefined;
7
+ variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface AlertProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {
10
10
  marginBottom?: "none" | "md";
@@ -4,7 +4,7 @@ import { VariantProps } from 'class-variance-authority';
4
4
  import { ElementType } from 'react';
5
5
 
6
6
  declare const badgeVariants: (props?: ({
7
- variant?: "neutral" | "error" | "success" | "default" | "secondary" | "destructive" | "outline" | "warning" | "info" | null | undefined;
7
+ variant?: "default" | "secondary" | "destructive" | "outline" | "success" | "warning" | "error" | "info" | "neutral" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
10
10
  weight?: "normal" | "semibold" | "bold";
@@ -4,7 +4,7 @@ import { VariantProps } from 'class-variance-authority';
4
4
  import { ElementType } from 'react';
5
5
 
6
6
  declare const badgeVariants: (props?: ({
7
- variant?: "neutral" | "error" | "success" | "default" | "secondary" | "destructive" | "outline" | "warning" | "info" | null | undefined;
7
+ variant?: "default" | "secondary" | "destructive" | "outline" | "success" | "warning" | "error" | "info" | "neutral" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
10
10
  weight?: "normal" | "semibold" | "bold";
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare function BubbleGroup({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
7
7
  declare const bubbleVariants: (props?: ({
8
- variant?: "default" | "muted" | "ghost" | "secondary" | "destructive" | "outline" | "tinted" | null | undefined;
8
+ variant?: "default" | "muted" | "secondary" | "destructive" | "outline" | "ghost" | "tinted" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare function Bubble({ variant, align, className, ...props }: React.ComponentProps<"div"> & VariantProps<typeof bubbleVariants> & {
11
11
  align?: "start" | "end";
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare function BubbleGroup({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
7
7
  declare const bubbleVariants: (props?: ({
8
- variant?: "default" | "muted" | "ghost" | "secondary" | "destructive" | "outline" | "tinted" | null | undefined;
8
+ variant?: "default" | "muted" | "secondary" | "destructive" | "outline" | "ghost" | "tinted" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare function Bubble({ variant, align, className, ...props }: React.ComponentProps<"div"> & VariantProps<typeof bubbleVariants> & {
11
11
  align?: "start" | "end";
@@ -4,8 +4,8 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const buttonVariants: (props?: ({
7
- variant?: "link" | "default" | "ghost" | "secondary" | "destructive" | "outline" | "outline-muted" | "quiet" | "ghost-destructive" | "link-muted" | "inverted" | "status-error" | "status-warning" | "status-muted" | null | undefined;
8
- size?: "filter" | "status" | "toolbar" | "sm" | "lg" | "default" | "micro" | "tone" | "compact" | "hero" | "icon" | "icon-lg" | "icon-sm" | "icon-md" | "icon-xs" | "icon-compact" | "icon-micro" | "bare" | "voice-sm" | "voice" | "suggestion" | null | undefined;
7
+ variant?: "link" | "default" | "secondary" | "destructive" | "outline" | "outline-muted" | "ghost" | "quiet" | "ghost-destructive" | "link-muted" | "inverted" | "status-error" | "status-warning" | "status-muted" | null | undefined;
8
+ size?: "filter" | "status" | "toolbar" | "sm" | "lg" | "default" | "micro" | "compact" | "hero" | "icon" | "icon-lg" | "icon-sm" | "icon-md" | "icon-xs" | "icon-compact" | "icon-micro" | "bare" | "voice-sm" | "voice" | "suggestion" | "tone" | null | undefined;
9
9
  width?: "auto" | "full" | "responsive" | null | undefined;
10
10
  align?: "center" | "start" | null | undefined;
11
11
  shrink?: boolean | null | undefined;
@@ -4,8 +4,8 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const buttonVariants: (props?: ({
7
- variant?: "link" | "default" | "ghost" | "secondary" | "destructive" | "outline" | "outline-muted" | "quiet" | "ghost-destructive" | "link-muted" | "inverted" | "status-error" | "status-warning" | "status-muted" | null | undefined;
8
- size?: "filter" | "status" | "toolbar" | "sm" | "lg" | "default" | "micro" | "tone" | "compact" | "hero" | "icon" | "icon-lg" | "icon-sm" | "icon-md" | "icon-xs" | "icon-compact" | "icon-micro" | "bare" | "voice-sm" | "voice" | "suggestion" | null | undefined;
7
+ variant?: "link" | "default" | "secondary" | "destructive" | "outline" | "outline-muted" | "ghost" | "quiet" | "ghost-destructive" | "link-muted" | "inverted" | "status-error" | "status-warning" | "status-muted" | null | undefined;
8
+ size?: "filter" | "status" | "toolbar" | "sm" | "lg" | "default" | "micro" | "compact" | "hero" | "icon" | "icon-lg" | "icon-sm" | "icon-md" | "icon-xs" | "icon-compact" | "icon-micro" | "bare" | "voice-sm" | "voice" | "suggestion" | "tone" | null | undefined;
9
9
  width?: "auto" | "full" | "responsive" | null | undefined;
10
10
  align?: "center" | "start" | null | undefined;
11
11
  shrink?: boolean | null | undefined;
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
 
4
4
 
5
- var _chunkUW67GSZ4cjs = require('../chunk-UW67GSZ4.cjs');
5
+ var _chunk7QTFYEPEcjs = require('../chunk-7QTFYEPE.cjs');
6
6
 
7
7
 
8
8
 
@@ -10,7 +10,7 @@ var _chunkUW67GSZ4cjs = require('../chunk-UW67GSZ4.cjs');
10
10
  var _chunk2BTDBZYNcjs = require('../chunk-2BTDBZYN.cjs');
11
11
 
12
12
 
13
- var _chunkHTCW6AEHcjs = require('../chunk-HTCW6AEH.cjs');
13
+ var _chunkKQBXAQAYcjs = require('../chunk-KQBXAQAY.cjs');
14
14
 
15
15
 
16
16
 
@@ -75,7 +75,7 @@ var _chunkFYRQFEU4cjs = require('../chunk-FYRQFEU4.cjs');
75
75
 
76
76
  var _chunk2KFZQJH5cjs = require('../chunk-2KFZQJH5.cjs');
77
77
  require('../chunk-PQUSJEXL.cjs');
78
- require('../chunk-XB2D4NQK.cjs');
78
+ require('../chunk-NKWHDI4C.cjs');
79
79
 
80
80
 
81
81
  var _chunkJDEXZGIYcjs = require('../chunk-JDEXZGIY.cjs');
@@ -86,7 +86,7 @@ require('../chunk-2BSFYU22.cjs');
86
86
 
87
87
 
88
88
  var _chunk4LXN6GLZcjs = require('../chunk-4LXN6GLZ.cjs');
89
- require('../chunk-O6F3LVZY.cjs');
89
+ require('../chunk-ZZ7ICQR2.cjs');
90
90
 
91
91
 
92
92
  var _chunkR35FT53Gcjs = require('../chunk-R35FT53G.cjs');
@@ -465,7 +465,7 @@ function ChatInput({
465
465
  className
466
466
  ),
467
467
  children: [
468
- liveVoiceActive && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7LDJAXRXcjs.InputGroupAddon, { align: "block-start", className: "w-full border-b border-border", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUW67GSZ4cjs.VoiceSessionControls, { ...voiceSession }) }),
468
+ liveVoiceActive && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7LDJAXRXcjs.InputGroupAddon, { align: "block-start", className: "w-full cursor-default border-b border-border p-0 [.border-b]:pb-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QTFYEPEcjs.VoiceSessionControls, { ...voiceSession }) }),
469
469
  attachments.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
470
470
  ChatAttachmentList,
471
471
  {
@@ -489,11 +489,10 @@ function ChatInput({
489
489
  },
490
490
  placeholder,
491
491
  rows: compact ? 1 : composerSize.rows,
492
- wrap: compact ? "off" : void 0,
493
492
  disabled: isDisabled,
494
493
  autoFocus,
495
494
  className: _chunkKWLSBTB2cjs.cn.call(void 0,
496
- compact ? "h-[44px] min-h-[44px] max-h-[44px] min-w-0 field-sizing-fixed overflow-hidden whitespace-nowrap text-ellipsis" : composerSize.minHeight,
495
+ compact ? "min-h-[44px] max-h-24 min-w-0" : composerSize.minHeight,
497
496
  // Grows with the text, then scrolls rather than pushing the thread away.
498
497
  "leading-relaxed disabled:opacity-70 placeholder:text-sm",
499
498
  !compact && "max-h-48",
@@ -504,14 +503,14 @@ function ChatInput({
504
503
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
505
504
  _chunk7LDJAXRXcjs.InputGroupAddon,
506
505
  {
507
- align: compact ? "inline-end" : "block-end",
506
+ align: "block-end",
508
507
  "data-slot": "chat-input-actions",
509
508
  onClick: (event) => {
510
509
  if (!event.currentTarget.contains(event.target)) return;
511
510
  if (!event.target.closest("button")) _optionalChain([ref, 'access', _3 => _3.current, 'optionalAccess', _4 => _4.focus, 'call', _5 => _5()]);
512
511
  },
513
512
  className: _chunkKWLSBTB2cjs.cn.call(void 0,
514
- compact ? "shrink-0 gap-0 p-1" : "gap-2",
513
+ compact ? "gap-1 px-2 pb-2 pt-0" : "gap-2",
515
514
  !compact && (spacious ? "px-5 pb-5 pt-1" : "border-t border-border px-3 py-2.5")
516
515
  ),
517
516
  children: [
@@ -539,9 +538,10 @@ function ChatInput({
539
538
  className: _chunkKWLSBTB2cjs.cn.call(void 0, "min-w-0 flex-1 truncate px-1 text-center text-xs font-normal text-muted-foreground sm:px-2 sm:text-sm", compact && "hidden"),
540
539
  children: helperText
541
540
  }
542
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: compact ? "hidden" : "flex-1" }),
541
+ ) : null,
542
+ (!helperText || compact) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1" }),
543
543
  voice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
544
- _chunkHTCW6AEHcjs.VoiceDictationButton,
544
+ _chunkKQBXAQAYcjs.VoiceDictationButton,
545
545
  {
546
546
  size: "icon",
547
547
  title: voiceTitle,
@@ -555,7 +555,7 @@ function ChatInput({
555
555
  )
556
556
  }
557
557
  ),
558
- voiceSession && !liveVoiceActive && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUW67GSZ4cjs.VoiceSessionControls, { ...voiceSession, disabled: voiceSession.disabled || isDisabled }),
558
+ voiceSession && !liveVoiceActive && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QTFYEPEcjs.VoiceSessionControls, { ...voiceSession, disabled: voiceSession.disabled || isDisabled }),
559
559
  submitLabel ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
560
560
  _chunkJDEXZGIYcjs.Button,
561
561
  {
@@ -614,9 +614,9 @@ function VoiceHero({
614
614
  }) {
615
615
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-5 py-6", children: [
616
616
  voiceSession ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
617
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUW67GSZ4cjs.VoiceSessionControls, { ...voiceSession, size: "hero" }),
617
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QTFYEPEcjs.VoiceSessionControls, { ...voiceSession, size: "hero" }),
618
618
  voice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
619
- _chunkHTCW6AEHcjs.VoiceDictationButton,
619
+ _chunkKQBXAQAYcjs.VoiceDictationButton,
620
620
  {
621
621
  size: "icon",
622
622
  title: voiceTitle,
@@ -626,7 +626,7 @@ function VoiceHero({
626
626
  }
627
627
  )
628
628
  ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
629
- _chunkHTCW6AEHcjs.VoiceDictationButton,
629
+ _chunkKQBXAQAYcjs.VoiceDictationButton,
630
630
  {
631
631
  size: "lg",
632
632
  title: voiceTitle,
@@ -187,7 +187,7 @@ interface ChatInputProps {
187
187
  /** Visual density for the complete composer surface. */
188
188
  appearance?: "default" | "spacious";
189
189
  /**
190
- * Fold an empty, unfocused composer into one row. Focusing its textarea
190
+ * Fold an empty, unfocused composer into a short text row and control bar. Focusing its textarea
191
191
  * expands it; drafts and staged files always keep it expanded. Chat enables
192
192
  * this only for an active mobile conversation with `mobileCompactComposer`.
193
193
  */
@@ -326,7 +326,7 @@ interface ChatProps {
326
326
  composerAppearance?: ChatInputProps["appearance"];
327
327
  /**
328
328
  * On phones (below 768px), fold an active conversation's empty composer
329
- * into one row until its textarea is focused. Drafts and files stay
329
+ * into a short text row above its controls until the textarea is focused. Drafts and files stay
330
330
  * expanded. Desktop and the new-conversation composer are unchanged.
331
331
  */
332
332
  mobileCompactComposer?: boolean;
@@ -187,7 +187,7 @@ interface ChatInputProps {
187
187
  /** Visual density for the complete composer surface. */
188
188
  appearance?: "default" | "spacious";
189
189
  /**
190
- * Fold an empty, unfocused composer into one row. Focusing its textarea
190
+ * Fold an empty, unfocused composer into a short text row and control bar. Focusing its textarea
191
191
  * expands it; drafts and staged files always keep it expanded. Chat enables
192
192
  * this only for an active mobile conversation with `mobileCompactComposer`.
193
193
  */
@@ -326,7 +326,7 @@ interface ChatProps {
326
326
  composerAppearance?: ChatInputProps["appearance"];
327
327
  /**
328
328
  * On phones (below 768px), fold an active conversation's empty composer
329
- * into one row until its textarea is focused. Drafts and files stay
329
+ * into a short text row above its controls until the textarea is focused. Drafts and files stay
330
330
  * expanded. Desktop and the new-conversation composer are unchanged.
331
331
  */
332
332
  mobileCompactComposer?: boolean;
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
  import {
4
4
  VoiceSessionControls
5
- } from "../chunk-KUG4ONYC.js";
5
+ } from "../chunk-UOVA4YKW.js";
6
6
  import {
7
7
  Trace,
8
8
  TraceLine,
@@ -10,7 +10,7 @@ import {
10
10
  } from "../chunk-Z45YKVAM.js";
11
11
  import {
12
12
  VoiceDictationButton
13
- } from "../chunk-KWV5KTOA.js";
13
+ } from "../chunk-T3XMHWYV.js";
14
14
  import {
15
15
  Suggestion,
16
16
  Suggestions
@@ -75,7 +75,7 @@ import {
75
75
  ActionDock
76
76
  } from "../chunk-42RTTHND.js";
77
77
  import "../chunk-QMA3WVB7.js";
78
- import "../chunk-VBKJXNEL.js";
78
+ import "../chunk-5OF6D3GH.js";
79
79
  import {
80
80
  Button
81
81
  } from "../chunk-W326GKML.js";
@@ -86,7 +86,7 @@ import "../chunk-GJ7S3L6R.js";
86
86
  import {
87
87
  useCopyToClipboard
88
88
  } from "../chunk-ZWZAAGQF.js";
89
- import "../chunk-M2ZNC3TK.js";
89
+ import "../chunk-HLAHOVEI.js";
90
90
  import {
91
91
  useIsMobile
92
92
  } from "../chunk-PIU5SSUV.js";
@@ -465,7 +465,7 @@ function ChatInput({
465
465
  className
466
466
  ),
467
467
  children: [
468
- liveVoiceActive && /* @__PURE__ */ jsx(InputGroupAddon, { align: "block-start", className: "w-full border-b border-border", children: /* @__PURE__ */ jsx(VoiceSessionControls, { ...voiceSession }) }),
468
+ liveVoiceActive && /* @__PURE__ */ jsx(InputGroupAddon, { align: "block-start", className: "w-full cursor-default border-b border-border p-0 [.border-b]:pb-0", children: /* @__PURE__ */ jsx(VoiceSessionControls, { ...voiceSession }) }),
469
469
  attachments.length > 0 && /* @__PURE__ */ jsx(
470
470
  ChatAttachmentList,
471
471
  {
@@ -489,11 +489,10 @@ function ChatInput({
489
489
  },
490
490
  placeholder,
491
491
  rows: compact ? 1 : composerSize.rows,
492
- wrap: compact ? "off" : void 0,
493
492
  disabled: isDisabled,
494
493
  autoFocus,
495
494
  className: cn(
496
- compact ? "h-[44px] min-h-[44px] max-h-[44px] min-w-0 field-sizing-fixed overflow-hidden whitespace-nowrap text-ellipsis" : composerSize.minHeight,
495
+ compact ? "min-h-[44px] max-h-24 min-w-0" : composerSize.minHeight,
497
496
  // Grows with the text, then scrolls rather than pushing the thread away.
498
497
  "leading-relaxed disabled:opacity-70 placeholder:text-sm",
499
498
  !compact && "max-h-48",
@@ -504,14 +503,14 @@ function ChatInput({
504
503
  /* @__PURE__ */ jsxs(
505
504
  InputGroupAddon,
506
505
  {
507
- align: compact ? "inline-end" : "block-end",
506
+ align: "block-end",
508
507
  "data-slot": "chat-input-actions",
509
508
  onClick: (event) => {
510
509
  if (!event.currentTarget.contains(event.target)) return;
511
510
  if (!event.target.closest("button")) ref.current?.focus();
512
511
  },
513
512
  className: cn(
514
- compact ? "shrink-0 gap-0 p-1" : "gap-2",
513
+ compact ? "gap-1 px-2 pb-2 pt-0" : "gap-2",
515
514
  !compact && (spacious ? "px-5 pb-5 pt-1" : "border-t border-border px-3 py-2.5")
516
515
  ),
517
516
  children: [
@@ -539,7 +538,8 @@ function ChatInput({
539
538
  className: cn("min-w-0 flex-1 truncate px-1 text-center text-xs font-normal text-muted-foreground sm:px-2 sm:text-sm", compact && "hidden"),
540
539
  children: helperText
541
540
  }
542
- ) : /* @__PURE__ */ jsx("div", { className: compact ? "hidden" : "flex-1" }),
541
+ ) : null,
542
+ (!helperText || compact) && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
543
543
  voice && /* @__PURE__ */ jsx(
544
544
  VoiceDictationButton,
545
545
  {
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
 
4
4
 
5
- var _chunkO6F3LVZYcjs = require('../chunk-O6F3LVZY.cjs');
5
+ var _chunkZZ7ICQR2cjs = require('../chunk-ZZ7ICQR2.cjs');
6
6
 
7
7
 
8
- exports.DictationProvider = _chunkO6F3LVZYcjs.DictationProvider;
8
+ exports.DictationProvider = _chunkZZ7ICQR2cjs.DictationProvider;
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
  import {
4
4
  DictationProvider
5
- } from "../chunk-M2ZNC3TK.js";
5
+ } from "../chunk-HLAHOVEI.js";
6
6
  export {
7
7
  DictationProvider
8
8
  };
@@ -2,10 +2,12 @@
2
2
  "use client";
3
3
 
4
4
 
5
- var _chunkHTCW6AEHcjs = require('../chunk-HTCW6AEH.cjs');
5
+ var _chunkKQBXAQAYcjs = require('../chunk-KQBXAQAY.cjs');
6
+ require('../chunk-NKWHDI4C.cjs');
6
7
  require('../chunk-JDEXZGIY.cjs');
7
8
  require('../chunk-KWLSBTB2.cjs');
8
- require('../chunk-O6F3LVZY.cjs');
9
+ require('../chunk-2BSFYU22.cjs');
10
+ require('../chunk-ZZ7ICQR2.cjs');
9
11
 
10
12
 
11
- exports.VoiceDictationButton = _chunkHTCW6AEHcjs.VoiceDictationButton;
13
+ exports.VoiceDictationButton = _chunkKQBXAQAYcjs.VoiceDictationButton;
@@ -6,9 +6,9 @@ interface VoiceDictationButtonProps {
6
6
  onCommit: (text: string) => void;
7
7
  /** Fired if the user closes the overlay without committing. */
8
8
  onCancel?: () => void;
9
- /** Optional title shown above the live transcript inside the overlay. */
9
+ /** Title shown in the compact recorder. */
10
10
  title?: ReactNode;
11
- /** Tagline shown under the title (small mono caption). Defaults to "listening". */
11
+ /** Recording status label. Defaults to "Recording". */
12
12
  caption?: string;
13
13
  /** BCP-47 language tag. Defaults to "en-US". */
14
14
  lang?: string;
@@ -28,13 +28,9 @@ interface VoiceDictationButtonProps {
28
28
  shrink?: boolean;
29
29
  }
30
30
  /**
31
- * Mic button that opens a fullscreen dictation overlay (portal). When the
32
- * user taps "Done" the captured transcript is committed via onCommit and
33
- * the overlay closes. The overlay strips the page chrome so the user can
34
- * focus on speaking.
35
- *
36
- * Sibling to `<VoiceInput>` which streams chunks inline. Use this when
37
- * dictation should take over the screen instead of typing-into-an-input.
31
+ * Opens a compact portaled recorder. A fixed panel also works when its
32
+ * trigger is hidden or sits inside another dialog. Done finishes the take
33
+ * and commits its transcript once; Cancel discards it.
38
34
  */
39
35
  declare function VoiceDictationButton({ onCommit, onCancel, title, caption, lang, continuous, className, size, showLabel, children, disabled, visibility, shrink, }: VoiceDictationButtonProps): react_jsx_runtime.JSX.Element | null;
40
36
 
@@ -6,9 +6,9 @@ interface VoiceDictationButtonProps {
6
6
  onCommit: (text: string) => void;
7
7
  /** Fired if the user closes the overlay without committing. */
8
8
  onCancel?: () => void;
9
- /** Optional title shown above the live transcript inside the overlay. */
9
+ /** Title shown in the compact recorder. */
10
10
  title?: ReactNode;
11
- /** Tagline shown under the title (small mono caption). Defaults to "listening". */
11
+ /** Recording status label. Defaults to "Recording". */
12
12
  caption?: string;
13
13
  /** BCP-47 language tag. Defaults to "en-US". */
14
14
  lang?: string;
@@ -28,13 +28,9 @@ interface VoiceDictationButtonProps {
28
28
  shrink?: boolean;
29
29
  }
30
30
  /**
31
- * Mic button that opens a fullscreen dictation overlay (portal). When the
32
- * user taps "Done" the captured transcript is committed via onCommit and
33
- * the overlay closes. The overlay strips the page chrome so the user can
34
- * focus on speaking.
35
- *
36
- * Sibling to `<VoiceInput>` which streams chunks inline. Use this when
37
- * dictation should take over the screen instead of typing-into-an-input.
31
+ * Opens a compact portaled recorder. A fixed panel also works when its
32
+ * trigger is hidden or sits inside another dialog. Done finishes the take
33
+ * and commits its transcript once; Cancel discards it.
38
34
  */
39
35
  declare function VoiceDictationButton({ onCommit, onCancel, title, caption, lang, continuous, className, size, showLabel, children, disabled, visibility, shrink, }: VoiceDictationButtonProps): react_jsx_runtime.JSX.Element | null;
40
36
 
@@ -2,10 +2,12 @@
2
2
  "use client";
3
3
  import {
4
4
  VoiceDictationButton
5
- } from "../chunk-KWV5KTOA.js";
5
+ } from "../chunk-T3XMHWYV.js";
6
+ import "../chunk-5OF6D3GH.js";
6
7
  import "../chunk-W326GKML.js";
7
8
  import "../chunk-G6SRSWXB.js";
8
- import "../chunk-M2ZNC3TK.js";
9
+ import "../chunk-GJ7S3L6R.js";
10
+ import "../chunk-HLAHOVEI.js";
9
11
  export {
10
12
  VoiceDictationButton
11
13
  };
@@ -2,11 +2,11 @@
2
2
  "use client";
3
3
 
4
4
 
5
- var _chunkUW67GSZ4cjs = require('../chunk-UW67GSZ4.cjs');
6
- require('../chunk-XB2D4NQK.cjs');
5
+ var _chunk7QTFYEPEcjs = require('../chunk-7QTFYEPE.cjs');
6
+ require('../chunk-NKWHDI4C.cjs');
7
7
  require('../chunk-JDEXZGIY.cjs');
8
8
  require('../chunk-KWLSBTB2.cjs');
9
9
  require('../chunk-2BSFYU22.cjs');
10
10
 
11
11
 
12
- exports.VoiceSessionControls = _chunkUW67GSZ4cjs.VoiceSessionControls;
12
+ exports.VoiceSessionControls = _chunk7QTFYEPEcjs.VoiceSessionControls;
@@ -15,15 +15,17 @@ interface VoiceSessionControlsProps {
15
15
  /** Prevent starting a new session; ending an active session stays available. */
16
16
  disabled?: boolean;
17
17
  error?: string | null;
18
+ /** The latest user utterance supplied by the host; never submits a message. */
19
+ transcript?: string;
18
20
  /** Audio levels supplied by the host; no media connection is created by the kit. */
19
21
  volumeBands?: number[];
20
22
  /** Optional external audio store, so level changes only re-render these controls. */
21
23
  audioLevels?: VoiceAudioLevelsSource;
22
- labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry", string>>;
24
+ labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry" | "endShort" | "muteShort" | "unmuteShort" | "transcriptPlaceholder", string>>;
23
25
  size?: "icon" | "hero";
24
26
  className?: string;
25
27
  }
26
28
  /** Transport-independent voice controls. The conversation stays visible while speaking. */
27
- declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
29
+ declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, transcript, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
28
30
 
29
31
  export { type VoiceAudioLevelsSource, VoiceSessionControls, type VoiceSessionControlsProps, type VoiceSessionState };
@@ -15,15 +15,17 @@ interface VoiceSessionControlsProps {
15
15
  /** Prevent starting a new session; ending an active session stays available. */
16
16
  disabled?: boolean;
17
17
  error?: string | null;
18
+ /** The latest user utterance supplied by the host; never submits a message. */
19
+ transcript?: string;
18
20
  /** Audio levels supplied by the host; no media connection is created by the kit. */
19
21
  volumeBands?: number[];
20
22
  /** Optional external audio store, so level changes only re-render these controls. */
21
23
  audioLevels?: VoiceAudioLevelsSource;
22
- labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry", string>>;
24
+ labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry" | "endShort" | "muteShort" | "unmuteShort" | "transcriptPlaceholder", string>>;
23
25
  size?: "icon" | "hero";
24
26
  className?: string;
25
27
  }
26
28
  /** Transport-independent voice controls. The conversation stays visible while speaking. */
27
- declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
29
+ declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, transcript, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
28
30
 
29
31
  export { type VoiceAudioLevelsSource, VoiceSessionControls, type VoiceSessionControlsProps, type VoiceSessionState };
@@ -2,8 +2,8 @@
2
2
  "use client";
3
3
  import {
4
4
  VoiceSessionControls
5
- } from "../chunk-KUG4ONYC.js";
6
- import "../chunk-VBKJXNEL.js";
5
+ } from "../chunk-UOVA4YKW.js";
6
+ import "../chunk-5OF6D3GH.js";
7
7
  import "../chunk-W326GKML.js";
8
8
  import "../chunk-G6SRSWXB.js";
9
9
  import "../chunk-GJ7S3L6R.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epicbagel/saas-kit",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "Accessible React primitives, layout components and design tokens for SaaS apps, built on Radix UI and Tailwind CSS v4.",
5
5
  "license": "MIT",
6
6
  "keywords": [