@epicbagel/saas-kit 1.19.0 → 1.21.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.
@@ -0,0 +1,204 @@
1
+ "use client";
2
+ "use client";
3
+ import {
4
+ ChatInput,
5
+ ChatThread
6
+ } from "../chunk-C23Q4FRM.js";
7
+ import "../chunk-Z45YKVAM.js";
8
+ import "../chunk-ZGTPNSR7.js";
9
+ import "../chunk-KF4X37DP.js";
10
+ import "../chunk-IJG2B3Y2.js";
11
+ import "../chunk-IW4ZIXXG.js";
12
+ import "../chunk-OUZSIA5G.js";
13
+ import "../chunk-36LNA4WM.js";
14
+ import "../chunk-H4XH2PPU.js";
15
+ import "../chunk-GA5SX7FE.js";
16
+ import "../chunk-QTPPNK6F.js";
17
+ import "../chunk-6FC65AZQ.js";
18
+ import "../chunk-WHDHUYS6.js";
19
+ import "../chunk-VY5U4VGV.js";
20
+ import "../chunk-INNGGLMZ.js";
21
+ import "../chunk-4HWCNRK4.js";
22
+ import "../chunk-V4LE2HWP.js";
23
+ import "../chunk-ZRLUUZHK.js";
24
+ import "../chunk-F366BHWH.js";
25
+ import "../chunk-EIY5LLSP.js";
26
+ import "../chunk-NBUWGRQO.js";
27
+ import "../chunk-CYDICVH2.js";
28
+ import "../chunk-42RTTHND.js";
29
+ import "../chunk-QMA3WVB7.js";
30
+ import "../chunk-3OWGL4Q2.js";
31
+ import "../chunk-5OF6D3GH.js";
32
+ import {
33
+ Button
34
+ } from "../chunk-W326GKML.js";
35
+ import {
36
+ cn
37
+ } from "../chunk-G6SRSWXB.js";
38
+ import "../chunk-GJ7S3L6R.js";
39
+ import "../chunk-ZWZAAGQF.js";
40
+ import "../chunk-RPSRCB5O.js";
41
+ import "../chunk-PIU5SSUV.js";
42
+ import "../chunk-CS7DM3NV.js";
43
+
44
+ // src/primitives/workflow-assistant.tsx
45
+ import { forwardRef, useEffect, useId, useRef } from "react";
46
+ import { AudioLines, ChevronDown, Maximize2, Minimize2, Square } from "lucide-react";
47
+ import { jsx, jsxs } from "react/jsx-runtime";
48
+ var SESSION_LABELS = {
49
+ disconnected: "Voice chat",
50
+ connecting: "Connecting\u2026",
51
+ listening: "Listening\u2026",
52
+ thinking: "Thinking\u2026",
53
+ speaking: "Speaking",
54
+ reconnecting: "Reconnecting\u2026",
55
+ error: "Voice chat unavailable"
56
+ };
57
+ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
58
+ open,
59
+ onOpenChange,
60
+ expanded = false,
61
+ onExpandedChange,
62
+ title = "Voice review",
63
+ context,
64
+ description,
65
+ messages,
66
+ value,
67
+ onChange,
68
+ onSend,
69
+ voiceSession,
70
+ pending,
71
+ disabled,
72
+ error,
73
+ placeholder = "Describe an action\u2026",
74
+ besideCornerAction = false,
75
+ labels,
76
+ className
77
+ }, ref) {
78
+ const titleId = useId();
79
+ const statusId = useId();
80
+ const launcher = useRef(null);
81
+ const heading = useRef(null);
82
+ const moveFocus = useRef(false);
83
+ useEffect(() => {
84
+ if (!moveFocus.current) return;
85
+ moveFocus.current = false;
86
+ (open ? heading.current : launcher.current)?.focus();
87
+ }, [open]);
88
+ const toggle = (next) => {
89
+ moveFocus.current = true;
90
+ onOpenChange(next);
91
+ };
92
+ const startDisabled = pending || disabled || voiceSession?.disabled;
93
+ const active = voiceSession && voiceSession.state !== "disconnected" && voiceSession.state !== "error";
94
+ const status = voiceSession && (voiceSession.muted && voiceSession.state === "listening" ? voiceSession.labels?.muted ?? "Microphone muted" : voiceSession.labels?.[voiceSession.state] ?? SESSION_LABELS[voiceSession.state]);
95
+ if (!open) return /* @__PURE__ */ jsxs(
96
+ "aside",
97
+ {
98
+ ref,
99
+ "data-slot": "workflow-assistant-launcher",
100
+ "aria-label": title,
101
+ className: cn("fixed bottom-[calc(1.5rem+env(safe-area-inset-bottom))] z-40 flex max-w-[calc(100vw-9rem)] items-center gap-1", besideCornerAction ? "right-32 md:right-36" : "right-6 md:right-8", className),
102
+ children: [
103
+ /* @__PURE__ */ jsxs(
104
+ Button,
105
+ {
106
+ ref: launcher,
107
+ type: "button",
108
+ shape: "pill",
109
+ className: "min-h-12 min-w-12 max-w-full gap-2 shadow-lg",
110
+ disabled: startDisabled && !active,
111
+ "aria-label": active ? title : labels?.start ?? "Start voice review",
112
+ "aria-expanded": false,
113
+ "aria-describedby": active ? statusId : void 0,
114
+ onClick: () => {
115
+ toggle(true);
116
+ if (!active && !startDisabled) voiceSession?.onStart();
117
+ },
118
+ children: [
119
+ /* @__PURE__ */ jsx(AudioLines, { "aria-hidden": "true", className: "shrink-0" }),
120
+ /* @__PURE__ */ jsx("span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : title })
121
+ ]
122
+ }
123
+ ),
124
+ active && /* @__PURE__ */ jsx(
125
+ Button,
126
+ {
127
+ type: "button",
128
+ variant: "outline",
129
+ shape: "circle",
130
+ size: "icon",
131
+ className: "min-h-12 min-w-12 bg-background shadow-lg",
132
+ onClick: () => {
133
+ launcher.current?.focus();
134
+ voiceSession.onEnd();
135
+ },
136
+ "aria-label": labels?.end ?? voiceSession.labels?.end ?? "End voice chat",
137
+ children: /* @__PURE__ */ jsx(Square, { "aria-hidden": "true" })
138
+ }
139
+ )
140
+ ]
141
+ }
142
+ );
143
+ return /* @__PURE__ */ jsxs(
144
+ "aside",
145
+ {
146
+ ref,
147
+ "data-slot": "workflow-assistant",
148
+ "aria-labelledby": titleId,
149
+ className: cn(
150
+ "fixed inset-x-2 bottom-[calc(1rem+env(safe-area-inset-bottom))] z-40 flex min-h-0 flex-col overflow-y-auto overscroll-contain rounded-2xl border bg-background shadow-xl sm:inset-x-auto sm:right-6 sm:w-[28rem] md:right-8",
151
+ expanded ? "h-[calc(100dvh-6rem)]" : "max-h-[min(36rem,70dvh)]",
152
+ className
153
+ ),
154
+ children: [
155
+ /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-10 flex shrink-0 items-start gap-2 border-b bg-background p-3", children: [
156
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
157
+ /* @__PURE__ */ jsx("h2", { ref: heading, tabIndex: -1, id: titleId, className: "text-sm font-semibold", children: title }),
158
+ /* @__PURE__ */ jsx("p", { title: context, className: "mt-1 truncate text-xs text-muted-foreground", children: context })
159
+ ] }),
160
+ onExpandedChange && /* @__PURE__ */ jsx(
161
+ Button,
162
+ {
163
+ type: "button",
164
+ variant: "ghost",
165
+ size: "icon",
166
+ "aria-label": expanded ? labels?.collapse ?? "Reduce panel" : labels?.expand ?? "Expand panel",
167
+ onClick: () => onExpandedChange(!expanded),
168
+ children: expanded ? /* @__PURE__ */ jsx(Minimize2, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true" })
169
+ }
170
+ ),
171
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": labels?.minimize ?? "Minimize voice review", onClick: () => toggle(false), children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
172
+ ] }),
173
+ description && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-4 py-2 text-xs text-muted-foreground", children: description }),
174
+ /* @__PURE__ */ jsx(
175
+ ChatThread,
176
+ {
177
+ messages,
178
+ pending,
179
+ maxHeight: expanded ? "60dvh" : "32dvh",
180
+ className: cn("flex-1 px-3", messages.length > 0 || pending ? "min-h-24" : "min-h-0")
181
+ }
182
+ ),
183
+ error && /* @__PURE__ */ jsx("p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
184
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 p-2", children: /* @__PURE__ */ jsx(
185
+ ChatInput,
186
+ {
187
+ value,
188
+ onChange,
189
+ onSend,
190
+ disabled,
191
+ pending,
192
+ placeholder,
193
+ size: "sm",
194
+ voice: false,
195
+ voiceSession
196
+ }
197
+ ) })
198
+ ]
199
+ }
200
+ );
201
+ });
202
+ export {
203
+ WorkflowAssistant
204
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epicbagel/saas-kit",
3
- "version": "1.19.0",
3
+ "version": "1.21.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": [
@@ -1290,6 +1290,16 @@
1290
1290
  "default": "./dist/primitives/voice-session-controls.cjs"
1291
1291
  }
1292
1292
  },
1293
+ "./primitives/workflow-assistant": {
1294
+ "import": {
1295
+ "types": "./dist/primitives/workflow-assistant.d.ts",
1296
+ "default": "./dist/primitives/workflow-assistant.js"
1297
+ },
1298
+ "require": {
1299
+ "types": "./dist/primitives/workflow-assistant.d.cts",
1300
+ "default": "./dist/primitives/workflow-assistant.cjs"
1301
+ }
1302
+ },
1293
1303
  "./hooks/use-agent-audio-visualizer-bar": {
1294
1304
  "import": {
1295
1305
  "types": "./dist/hooks/use-agent-audio-visualizer-bar.d.ts",
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
 
11
- var _chunk2BHI5ZWJcjs = require('./chunk-2BHI5ZWJ.cjs');
11
+ var _chunkWDXEJDMOcjs = require('./chunk-WDXEJDMO.cjs');
12
12
 
13
13
 
14
14
 
@@ -18,7 +18,7 @@ var _chunk2BHI5ZWJcjs = require('./chunk-2BHI5ZWJ.cjs');
18
18
 
19
19
 
20
20
 
21
- var _chunkWDXEJDMOcjs = require('./chunk-WDXEJDMO.cjs');
21
+ var _chunk2BHI5ZWJcjs = require('./chunk-2BHI5ZWJ.cjs');
22
22
 
23
23
 
24
24
  var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
@@ -1,14 +1,4 @@
1
1
  "use client";
2
- import {
3
- Drawer,
4
- DrawerClose,
5
- DrawerContent,
6
- DrawerDescription,
7
- DrawerFooter,
8
- DrawerHeader,
9
- DrawerTitle,
10
- DrawerTrigger
11
- } from "./chunk-4HWCNRK4.js";
12
2
  import {
13
3
  Dialog,
14
4
  DialogClose,
@@ -19,6 +9,16 @@ import {
19
9
  DialogTitle,
20
10
  DialogTrigger
21
11
  } from "./chunk-3QT5VYZ3.js";
12
+ import {
13
+ Drawer,
14
+ DrawerClose,
15
+ DrawerContent,
16
+ DrawerDescription,
17
+ DrawerFooter,
18
+ DrawerHeader,
19
+ DrawerTitle,
20
+ DrawerTrigger
21
+ } from "./chunk-4HWCNRK4.js";
22
22
  import {
23
23
  cn
24
24
  } from "./chunk-G6SRSWXB.js";