@epicbagel/saas-kit 1.16.0 → 1.18.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.
- package/README.md +22 -4
- package/dist/{chunk-6S6GD43V.js → chunk-2UYEMPOJ.js} +5 -3
- package/dist/{chunk-6YXKFVZU.cjs → chunk-AU5GUDOW.cjs} +5 -3
- package/dist/{chunk-QWUMIAYD.cjs → chunk-PH2TV7XI.cjs} +58 -25
- package/dist/{chunk-JKVVTFAP.js → chunk-ZGTPNSR7.js} +59 -26
- package/dist/primitives/chat.cjs +4 -4
- package/dist/primitives/chat.js +1 -1
- package/dist/primitives/connection.cjs +2 -2
- package/dist/primitives/connection.js +1 -1
- package/dist/primitives/page-header-actions.cjs +2 -2
- package/dist/primitives/page-header-actions.d.cts +7 -4
- package/dist/primitives/page-header-actions.d.ts +7 -4
- package/dist/primitives/page-header-actions.js +1 -1
- package/dist/primitives/voice-dictation-button.cjs +2 -2
- package/dist/primitives/voice-dictation-button.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,20 @@ npm install @epicbagel/saas-kit
|
|
|
15
15
|
Peer dependencies: `react` and `react-dom` (18 or 19), `lucide-react`
|
|
16
16
|
(`>=0.400.0 <2`), `react-icons` (5) and `tailwindcss` (4.3 or later).
|
|
17
17
|
|
|
18
|
+
## Page header actions
|
|
19
|
+
|
|
20
|
+
`PageHeaderActions` expands its actions on desktop and collapses them into
|
|
21
|
+
one menu on mobile. Use `presentation="menu"` to keep the same menu at every
|
|
22
|
+
width, giving long page titles more room. Its action order, nested menus,
|
|
23
|
+
disabled state, destructive treatment and callbacks stay the same.
|
|
24
|
+
`mobileLabel` and `mobileAriaLabel` name the menu trigger in either layout.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<PageHeader title="Senior Enterprise Account Executive · Example Company">
|
|
28
|
+
<PageHeaderActions presentation="menu" actions={actions} />
|
|
29
|
+
</PageHeader>
|
|
30
|
+
```
|
|
31
|
+
|
|
18
32
|
## Live voice in Chat
|
|
19
33
|
|
|
20
34
|
Pass a controlled `voiceSession` to `Chat` or `ChatInput` to show start, mute,
|
|
@@ -42,16 +56,20 @@ does not import a voice provider. Stop and release audio tracks before setting
|
|
|
42
56
|
Wrap the application in `DictationProvider` to use an authenticated transcription
|
|
43
57
|
API for every `VoiceDictationButton`, including buttons nested in chat, forms or
|
|
44
58
|
another component library. The recorder opens beside its microphone on desktop
|
|
45
|
-
and fills the screen below 768px
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
and fills the screen below 768px. Its roomy panel puts the title and close control
|
|
60
|
+
above a microphone, live audio bars and elapsed time, followed by the transcript
|
|
61
|
+
and Done/Cancel controls. The microphone and bars share the palette's first chart
|
|
62
|
+
colour; surfaces and buttons keep their normal theme. The bars use the recording
|
|
63
|
+
stream without opening a second microphone; native recognition has no meter and
|
|
64
|
+
shows no waveform. No device selector is shown because the capture API does not
|
|
65
|
+
offer device selection. Resizing keeps the current recording alive.
|
|
48
66
|
|
|
49
67
|
For hidden/programmatic triggers, it uses the focused visible button as the
|
|
50
68
|
desktop anchor. Hosts can pass an explicit `anchorRef` for a custom trigger.
|
|
51
69
|
Without a visible anchor it opens full-screen. Nested and sibling dialogs keep
|
|
52
70
|
their focus and cancellation behavior.
|
|
53
71
|
The recorder runs until **Done**, finishes the last words, then commits the returned text once. Failed requests keep the
|
|
54
|
-
take available for retry. Cancel
|
|
72
|
+
take available for retry. Cancel and the header's close control stop microphone tracks, abort the request and
|
|
55
73
|
ignores a late answer. The kit never persists audio or knows provider credentials.
|
|
56
74
|
|
|
57
75
|
```tsx
|
|
@@ -33,13 +33,14 @@ function MenuActions({ actions }) {
|
|
|
33
33
|
return actions.map((action) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
34
34
|
action.separatorBefore && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
35
35
|
action.items?.length ? /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
36
|
-
/* @__PURE__ */ jsx(DropdownMenuSubTrigger, { disabled: action.disabled, children: /* @__PURE__ */ jsx(MenuActionContent, { action }) }),
|
|
36
|
+
/* @__PURE__ */ jsx(DropdownMenuSubTrigger, { disabled: action.disabled, title: action.title, children: /* @__PURE__ */ jsx(MenuActionContent, { action }) }),
|
|
37
37
|
/* @__PURE__ */ jsx(DropdownMenuSubContent, { children: /* @__PURE__ */ jsx(MenuActions, { actions: action.items }) })
|
|
38
38
|
] }) : /* @__PURE__ */ jsx(
|
|
39
39
|
DropdownMenuItem,
|
|
40
40
|
{
|
|
41
41
|
disabled: action.disabled,
|
|
42
42
|
tone: action.tone,
|
|
43
|
+
title: action.title,
|
|
43
44
|
onSelect: action.onSelect,
|
|
44
45
|
className: action.description ? "items-start" : void 0,
|
|
45
46
|
children: /* @__PURE__ */ jsx(MenuActionContent, { action })
|
|
@@ -49,6 +50,7 @@ function MenuActions({ actions }) {
|
|
|
49
50
|
}
|
|
50
51
|
function PageHeaderActions({
|
|
51
52
|
actions,
|
|
53
|
+
presentation = "responsive",
|
|
52
54
|
mobileLabel = "Actions",
|
|
53
55
|
mobileAriaLabel,
|
|
54
56
|
className
|
|
@@ -68,7 +70,7 @@ function PageHeaderActions({
|
|
|
68
70
|
return rank[priorityFor(left.action)] - rank[priorityFor(right.action)] || left.index - right.index;
|
|
69
71
|
}).map(({ action }) => action) : actions;
|
|
70
72
|
return /* @__PURE__ */ jsxs("div", { className: cn("shrink-0", className), children: [
|
|
71
|
-
/* @__PURE__ */ jsx(
|
|
73
|
+
presentation === "responsive" && /* @__PURE__ */ jsx(
|
|
72
74
|
"div",
|
|
73
75
|
{
|
|
74
76
|
className: "hidden items-center gap-2 sm:flex",
|
|
@@ -110,7 +112,7 @@ function PageHeaderActions({
|
|
|
110
112
|
)
|
|
111
113
|
}
|
|
112
114
|
),
|
|
113
|
-
/* @__PURE__ */ jsx("div", { className: "sm:hidden", "data-slot": "page-header-actions-mobile", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
115
|
+
/* @__PURE__ */ jsx("div", { className: presentation === "responsive" ? "sm:hidden" : void 0, "data-slot": "page-header-actions-mobile", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
114
116
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", variant: "outline", "aria-label": mobileAriaLabel, children: [
|
|
115
117
|
mobileLabel,
|
|
116
118
|
/* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" })
|
|
@@ -33,13 +33,14 @@ function MenuActions({ actions }) {
|
|
|
33
33
|
return actions.map((action) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _react.Fragment, { children: [
|
|
34
34
|
action.separatorBefore && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuSeparator, {}),
|
|
35
35
|
_optionalChain([action, 'access', _ => _.items, 'optionalAccess', _2 => _2.length]) ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZAITUDYDcjs.DropdownMenuSub, { children: [
|
|
36
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuSubTrigger, { disabled: action.disabled, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuActionContent, { action }) }),
|
|
36
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuSubTrigger, { disabled: action.disabled, title: action.title, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuActionContent, { action }) }),
|
|
37
37
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuSubContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuActions, { actions: action.items }) })
|
|
38
38
|
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
39
39
|
_chunkZAITUDYDcjs.DropdownMenuItem,
|
|
40
40
|
{
|
|
41
41
|
disabled: action.disabled,
|
|
42
42
|
tone: action.tone,
|
|
43
|
+
title: action.title,
|
|
43
44
|
onSelect: action.onSelect,
|
|
44
45
|
className: action.description ? "items-start" : void 0,
|
|
45
46
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuActionContent, { action })
|
|
@@ -49,6 +50,7 @@ function MenuActions({ actions }) {
|
|
|
49
50
|
}
|
|
50
51
|
function PageHeaderActions({
|
|
51
52
|
actions,
|
|
53
|
+
presentation = "responsive",
|
|
52
54
|
mobileLabel = "Actions",
|
|
53
55
|
mobileAriaLabel,
|
|
54
56
|
className
|
|
@@ -68,7 +70,7 @@ function PageHeaderActions({
|
|
|
68
70
|
return rank[priorityFor(left.action)] - rank[priorityFor(right.action)] || left.index - right.index;
|
|
69
71
|
}).map(({ action }) => action) : actions;
|
|
70
72
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "shrink-0", className), children: [
|
|
71
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
73
|
+
presentation === "responsive" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
72
74
|
"div",
|
|
73
75
|
{
|
|
74
76
|
className: "hidden items-center gap-2 sm:flex",
|
|
@@ -110,7 +112,7 @@ function PageHeaderActions({
|
|
|
110
112
|
)
|
|
111
113
|
}
|
|
112
114
|
),
|
|
113
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sm:hidden", "data-slot": "page-header-actions-mobile", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZAITUDYDcjs.DropdownMenu, { children: [
|
|
115
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: presentation === "responsive" ? "sm:hidden" : void 0, "data-slot": "page-header-actions-mobile", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZAITUDYDcjs.DropdownMenu, { children: [
|
|
114
116
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", size: "sm", variant: "outline", "aria-label": mobileAriaLabel, children: [
|
|
115
117
|
mobileLabel,
|
|
116
118
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { "aria-hidden": "true" })
|
|
@@ -118,40 +118,72 @@ function VoiceDictationButton({
|
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
const content = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
121
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex min-w-0 items-start justify-between gap-
|
|
122
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-w-0 space-y-1", children: [
|
|
123
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className:
|
|
124
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { role: "status", className: "flex items-center gap-
|
|
125
|
-
busy
|
|
121
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex min-w-0 shrink-0 items-start justify-between gap-4", !anchored && "w-full max-w-xl self-center"), children: [
|
|
122
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-w-0 space-y-2 pt-1", children: [
|
|
123
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "break-words text-xl font-semibold leading-tight", children: title || "Voice dictation" }),
|
|
124
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { role: "status", className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
125
|
+
busy && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LoaderCircle, { "aria-hidden": "true", className: "size-4 shrink-0 animate-spin motion-reduce:animate-none" }),
|
|
126
126
|
capture.state === "transcribing" ? "Finishing transcript\u2026" : capture.state === "requesting" ? "Starting dictation\u2026" : error ? "Recording not saved" : capture.state === "ready" ? "Ready" : caption
|
|
127
127
|
] })
|
|
128
128
|
] }),
|
|
129
|
-
/* @__PURE__ */ _jsxruntime.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
130
|
+
_chunkJDEXZGIYcjs.Button,
|
|
131
|
+
{
|
|
132
|
+
type: "button",
|
|
133
|
+
variant: "ghost",
|
|
134
|
+
size: "icon",
|
|
135
|
+
shape: "circle",
|
|
136
|
+
"aria-label": "Cancel dictation",
|
|
137
|
+
className: "size-[44px] shrink-0 text-muted-foreground [&_svg]:size-5",
|
|
138
|
+
onClick: handleCancel,
|
|
139
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.X, { "aria-hidden": "true", className: "size-5" })
|
|
140
|
+
}
|
|
141
|
+
)
|
|
134
142
|
] }),
|
|
135
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex flex-col gap-5", !anchored && "w-full max-w-xl flex-1 justify-center self-center py-6"), children: [
|
|
144
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { "data-slot": "dictation-meter", className: "flex min-w-0 items-center gap-3 py-5 text-[hsl(var(--chart-1))] sm:gap-5 sm:py-7", children: [
|
|
145
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
"aria-hidden": "true",
|
|
149
|
+
"data-slot": "dictation-microphone",
|
|
150
|
+
className: "flex size-[72px] shrink-0 items-center justify-center rounded-full bg-current/10 sm:size-[96px]",
|
|
151
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex size-[52px] items-center justify-center rounded-full bg-[hsl(var(--chart-1))] text-popover sm:size-[72px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Mic, { className: "size-7 sm:size-9" }) })
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
capture.audioLevels && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DictationWaveform, { source: capture.audioLevels, state: capture.state }),
|
|
155
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
156
|
+
"time",
|
|
157
|
+
{
|
|
158
|
+
"aria-label": "Recording duration",
|
|
159
|
+
dateTime: `PT${elapsed}S`,
|
|
160
|
+
className: "ml-auto shrink-0 font-mono text-xl tabular-nums text-muted-foreground sm:text-2xl",
|
|
161
|
+
children: [
|
|
162
|
+
Math.floor(elapsed / 60).toString().padStart(2, "0"),
|
|
163
|
+
":",
|
|
164
|
+
(elapsed % 60).toString().padStart(2, "0")
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
] }),
|
|
169
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { id: descriptionId, className: "text-base leading-relaxed text-muted-foreground", children: capture.state === "transcribing" ? "Finishing your last words\u2026" : capture.state === "requesting" ? "Allow microphone access to start." : error ? capture.canRetry ? "Retry this take or record again." : "Try recording again." : "Speak, then choose Done to add the text." }),
|
|
170
|
+
displayTranscript && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "max-h-48 overflow-y-auto break-words text-base leading-relaxed", children: [
|
|
139
171
|
transcript,
|
|
140
172
|
interim && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-muted-foreground", children: [
|
|
141
173
|
transcript ? " " : "",
|
|
142
174
|
interim
|
|
143
175
|
] })
|
|
144
176
|
] }),
|
|
145
|
-
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "alert", className: "text-
|
|
146
|
-
!error && capture.previewError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "status", className: "text-
|
|
177
|
+
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "alert", className: "text-sm leading-relaxed text-destructive", children: error }),
|
|
178
|
+
!error && capture.previewError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "status", className: "text-sm leading-relaxed text-muted-foreground", children: capture.previewError })
|
|
147
179
|
] }),
|
|
148
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "gap-2", anchored ? "flex flex-wrap items-center justify-end" : "mt-auto grid w-full max-w-xl grid-cols-
|
|
149
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { ref: cancelControl, type: "button", variant: "ghost",
|
|
150
|
-
capture.canRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", variant: "outline",
|
|
180
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "shrink-0 gap-3 pt-2", anchored ? "flex flex-wrap items-center justify-end" : "mt-auto grid w-full max-w-xl grid-cols-[auto_minmax(0,1fr)] self-center"), children: [
|
|
181
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { ref: cancelControl, type: "button", variant: "ghost", className: "min-h-[48px] px-5", onClick: handleCancel, children: "Cancel" }),
|
|
182
|
+
capture.canRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", variant: "outline", className: _chunkKWLSBTB2cjs.cn.call(void 0, "min-h-[48px] px-5", !anchored && "order-first col-span-2"), onClick: () => {
|
|
151
183
|
_optionalChain([cancelControl, 'access', _13 => _13.current, 'optionalAccess', _14 => _14.focus, 'call', _15 => _15({ preventScroll: true })]);
|
|
152
184
|
void capture.start();
|
|
153
185
|
}, children: "Record again" }),
|
|
154
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button",
|
|
186
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", className: "min-h-[48px] min-w-24 px-6", onClick: () => void handleDone(), disabled: busy, children: capture.state === "transcribing" ? "Transcribing\u2026" : capture.canRetry ? "Retry transcription" : error ? "Try again" : "Done" })
|
|
155
187
|
] })
|
|
156
188
|
] });
|
|
157
189
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
@@ -195,13 +227,13 @@ function VoiceDictationButton({
|
|
|
195
227
|
"data-placement": "anchored",
|
|
196
228
|
side: "top",
|
|
197
229
|
align: "center",
|
|
198
|
-
sideOffset:
|
|
230
|
+
sideOffset: 12,
|
|
199
231
|
collisionPadding: 12,
|
|
200
232
|
avoidCollisions: true,
|
|
201
233
|
onCloseAutoFocus: closeAutoFocus,
|
|
202
234
|
onKeyDown,
|
|
203
235
|
onEscapeKeyDown: (event) => event.stopPropagation(),
|
|
204
|
-
className: "z-[200] flex max-h-[var(--radix-popover-content-available-height)] w-
|
|
236
|
+
className: "z-[200] flex max-h-[var(--radix-popover-content-available-height)] w-[560px] max-w-[calc(100vw-24px)] flex-col gap-6 overflow-y-auto rounded-2xl border border-border bg-popover p-6 text-popover-foreground shadow-xl outline-hidden",
|
|
205
237
|
children: content
|
|
206
238
|
}
|
|
207
239
|
) })
|
|
@@ -221,7 +253,7 @@ function VoiceDictationButton({
|
|
|
221
253
|
onCloseAutoFocus: closeAutoFocus,
|
|
222
254
|
onKeyDown,
|
|
223
255
|
onEscapeKeyDown: (event) => event.stopPropagation(),
|
|
224
|
-
className: "fixed inset-0 z-[200] flex h-dvh w-screen flex-col gap-6 overflow-y-auto overscroll-contain bg-
|
|
256
|
+
className: "fixed inset-0 z-[200] flex h-dvh w-screen flex-col gap-6 overflow-y-auto overscroll-contain bg-popover px-5 pt-[max(1.5rem,env(safe-area-inset-top))] pb-[max(1.5rem,env(safe-area-inset-bottom))] text-popover-foreground outline-hidden",
|
|
225
257
|
children: [
|
|
226
258
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Title, { className: "sr-only", children: "Voice dictation" }),
|
|
227
259
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Description, { className: "sr-only", children: "Record your message, then choose Done to add the text. Cancel discards the recording." }),
|
|
@@ -234,7 +266,7 @@ function VoiceDictationButton({
|
|
|
234
266
|
}
|
|
235
267
|
var SILENCE = [];
|
|
236
268
|
var silence = () => SILENCE;
|
|
237
|
-
function DictationWaveform({ source, state
|
|
269
|
+
function DictationWaveform({ source, state }) {
|
|
238
270
|
const bands = _react.useSyncExternalStore.call(void 0, source.subscribe, source.getSnapshot, silence);
|
|
239
271
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
240
272
|
_chunkNKWHDI4Ccjs.AgentAudioVisualizerBar,
|
|
@@ -245,7 +277,8 @@ function DictationWaveform({ source, state, className }) {
|
|
|
245
277
|
barCount: 24,
|
|
246
278
|
state: state === "recording" ? "listening" : state === "transcribing" ? "thinking" : state === "requesting" ? "connecting" : "disconnected",
|
|
247
279
|
volumeBands: state === "recording" ? bands : void 0,
|
|
248
|
-
className:
|
|
280
|
+
className: "h-[64px] min-w-0 flex-1 gap-[3px] sm:h-[88px] sm:gap-[4px]",
|
|
281
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-[4px] max-w-[6px] flex-1 rounded-full bg-current/15 transition-colors duration-200 motion-reduce:transition-none data-[lk-highlighted=true]:bg-current" })
|
|
249
282
|
}
|
|
250
283
|
);
|
|
251
284
|
}
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "react";
|
|
24
24
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
25
25
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
26
|
-
import { Mic, LoaderCircle } from "lucide-react";
|
|
26
|
+
import { Mic, LoaderCircle, X } from "lucide-react";
|
|
27
27
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
28
28
|
function VoiceDictationButton({
|
|
29
29
|
onCommit,
|
|
@@ -118,40 +118,72 @@ function VoiceDictationButton({
|
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
121
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-start justify-between gap-
|
|
122
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
123
|
-
/* @__PURE__ */ jsx("h2", { className:
|
|
124
|
-
/* @__PURE__ */ jsxs("span", { role: "status", className: "flex items-center gap-
|
|
125
|
-
busy
|
|
121
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 shrink-0 items-start justify-between gap-4", !anchored && "w-full max-w-xl self-center"), children: [
|
|
122
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-2 pt-1", children: [
|
|
123
|
+
/* @__PURE__ */ jsx("h2", { className: "break-words text-xl font-semibold leading-tight", children: title || "Voice dictation" }),
|
|
124
|
+
/* @__PURE__ */ jsxs("span", { role: "status", className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
125
|
+
busy && /* @__PURE__ */ jsx(LoaderCircle, { "aria-hidden": "true", className: "size-4 shrink-0 animate-spin motion-reduce:animate-none" }),
|
|
126
126
|
capture.state === "transcribing" ? "Finishing transcript\u2026" : capture.state === "requesting" ? "Starting dictation\u2026" : error ? "Recording not saved" : capture.state === "ready" ? "Ready" : caption
|
|
127
127
|
] })
|
|
128
128
|
] }),
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
/* @__PURE__ */ jsx(
|
|
130
|
+
Button,
|
|
131
|
+
{
|
|
132
|
+
type: "button",
|
|
133
|
+
variant: "ghost",
|
|
134
|
+
size: "icon",
|
|
135
|
+
shape: "circle",
|
|
136
|
+
"aria-label": "Cancel dictation",
|
|
137
|
+
className: "size-[44px] shrink-0 text-muted-foreground [&_svg]:size-5",
|
|
138
|
+
onClick: handleCancel,
|
|
139
|
+
children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "size-5" })
|
|
140
|
+
}
|
|
141
|
+
)
|
|
134
142
|
] }),
|
|
135
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-5", !anchored && "w-full max-w-xl flex-1 justify-center self-center py-6"), children: [
|
|
144
|
+
/* @__PURE__ */ jsxs("div", { "data-slot": "dictation-meter", className: "flex min-w-0 items-center gap-3 py-5 text-[hsl(var(--chart-1))] sm:gap-5 sm:py-7", children: [
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
"aria-hidden": "true",
|
|
149
|
+
"data-slot": "dictation-microphone",
|
|
150
|
+
className: "flex size-[72px] shrink-0 items-center justify-center rounded-full bg-current/10 sm:size-[96px]",
|
|
151
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex size-[52px] items-center justify-center rounded-full bg-[hsl(var(--chart-1))] text-popover sm:size-[72px]", children: /* @__PURE__ */ jsx(Mic, { className: "size-7 sm:size-9" }) })
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
capture.audioLevels && /* @__PURE__ */ jsx(DictationWaveform, { source: capture.audioLevels, state: capture.state }),
|
|
155
|
+
/* @__PURE__ */ jsxs(
|
|
156
|
+
"time",
|
|
157
|
+
{
|
|
158
|
+
"aria-label": "Recording duration",
|
|
159
|
+
dateTime: `PT${elapsed}S`,
|
|
160
|
+
className: "ml-auto shrink-0 font-mono text-xl tabular-nums text-muted-foreground sm:text-2xl",
|
|
161
|
+
children: [
|
|
162
|
+
Math.floor(elapsed / 60).toString().padStart(2, "0"),
|
|
163
|
+
":",
|
|
164
|
+
(elapsed % 60).toString().padStart(2, "0")
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
] }),
|
|
169
|
+
/* @__PURE__ */ jsx("p", { id: descriptionId, className: "text-base leading-relaxed text-muted-foreground", children: capture.state === "transcribing" ? "Finishing your last words\u2026" : capture.state === "requesting" ? "Allow microphone access to start." : error ? capture.canRetry ? "Retry this take or record again." : "Try recording again." : "Speak, then choose Done to add the text." }),
|
|
170
|
+
displayTranscript && /* @__PURE__ */ jsxs("p", { className: "max-h-48 overflow-y-auto break-words text-base leading-relaxed", children: [
|
|
139
171
|
transcript,
|
|
140
172
|
interim && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
141
173
|
transcript ? " " : "",
|
|
142
174
|
interim
|
|
143
175
|
] })
|
|
144
176
|
] }),
|
|
145
|
-
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-
|
|
146
|
-
!error && capture.previewError && /* @__PURE__ */ jsx("p", { role: "status", className: "text-
|
|
177
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm leading-relaxed text-destructive", children: error }),
|
|
178
|
+
!error && capture.previewError && /* @__PURE__ */ jsx("p", { role: "status", className: "text-sm leading-relaxed text-muted-foreground", children: capture.previewError })
|
|
147
179
|
] }),
|
|
148
|
-
/* @__PURE__ */ jsxs("div", { className: cn("gap-2", anchored ? "flex flex-wrap items-center justify-end" : "mt-auto grid w-full max-w-xl grid-cols-
|
|
149
|
-
/* @__PURE__ */ jsx(Button, { ref: cancelControl, type: "button", variant: "ghost",
|
|
150
|
-
capture.canRetry && /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline",
|
|
180
|
+
/* @__PURE__ */ jsxs("div", { className: cn("shrink-0 gap-3 pt-2", anchored ? "flex flex-wrap items-center justify-end" : "mt-auto grid w-full max-w-xl grid-cols-[auto_minmax(0,1fr)] self-center"), children: [
|
|
181
|
+
/* @__PURE__ */ jsx(Button, { ref: cancelControl, type: "button", variant: "ghost", className: "min-h-[48px] px-5", onClick: handleCancel, children: "Cancel" }),
|
|
182
|
+
capture.canRetry && /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", className: cn("min-h-[48px] px-5", !anchored && "order-first col-span-2"), onClick: () => {
|
|
151
183
|
cancelControl.current?.focus({ preventScroll: true });
|
|
152
184
|
void capture.start();
|
|
153
185
|
}, children: "Record again" }),
|
|
154
|
-
/* @__PURE__ */ jsx(Button, { type: "button",
|
|
186
|
+
/* @__PURE__ */ jsx(Button, { type: "button", className: "min-h-[48px] min-w-24 px-6", onClick: () => void handleDone(), disabled: busy, children: capture.state === "transcribing" ? "Transcribing\u2026" : capture.canRetry ? "Retry transcription" : error ? "Try again" : "Done" })
|
|
155
187
|
] })
|
|
156
188
|
] });
|
|
157
189
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -195,13 +227,13 @@ function VoiceDictationButton({
|
|
|
195
227
|
"data-placement": "anchored",
|
|
196
228
|
side: "top",
|
|
197
229
|
align: "center",
|
|
198
|
-
sideOffset:
|
|
230
|
+
sideOffset: 12,
|
|
199
231
|
collisionPadding: 12,
|
|
200
232
|
avoidCollisions: true,
|
|
201
233
|
onCloseAutoFocus: closeAutoFocus,
|
|
202
234
|
onKeyDown,
|
|
203
235
|
onEscapeKeyDown: (event) => event.stopPropagation(),
|
|
204
|
-
className: "z-[200] flex max-h-[var(--radix-popover-content-available-height)] w-
|
|
236
|
+
className: "z-[200] flex max-h-[var(--radix-popover-content-available-height)] w-[560px] max-w-[calc(100vw-24px)] flex-col gap-6 overflow-y-auto rounded-2xl border border-border bg-popover p-6 text-popover-foreground shadow-xl outline-hidden",
|
|
205
237
|
children: content
|
|
206
238
|
}
|
|
207
239
|
) })
|
|
@@ -221,7 +253,7 @@ function VoiceDictationButton({
|
|
|
221
253
|
onCloseAutoFocus: closeAutoFocus,
|
|
222
254
|
onKeyDown,
|
|
223
255
|
onEscapeKeyDown: (event) => event.stopPropagation(),
|
|
224
|
-
className: "fixed inset-0 z-[200] flex h-dvh w-screen flex-col gap-6 overflow-y-auto overscroll-contain bg-
|
|
256
|
+
className: "fixed inset-0 z-[200] flex h-dvh w-screen flex-col gap-6 overflow-y-auto overscroll-contain bg-popover px-5 pt-[max(1.5rem,env(safe-area-inset-top))] pb-[max(1.5rem,env(safe-area-inset-bottom))] text-popover-foreground outline-hidden",
|
|
225
257
|
children: [
|
|
226
258
|
/* @__PURE__ */ jsx(DialogPrimitive.Title, { className: "sr-only", children: "Voice dictation" }),
|
|
227
259
|
/* @__PURE__ */ jsx(DialogPrimitive.Description, { className: "sr-only", children: "Record your message, then choose Done to add the text. Cancel discards the recording." }),
|
|
@@ -234,7 +266,7 @@ function VoiceDictationButton({
|
|
|
234
266
|
}
|
|
235
267
|
var SILENCE = [];
|
|
236
268
|
var silence = () => SILENCE;
|
|
237
|
-
function DictationWaveform({ source, state
|
|
269
|
+
function DictationWaveform({ source, state }) {
|
|
238
270
|
const bands = useSyncExternalStore(source.subscribe, source.getSnapshot, silence);
|
|
239
271
|
return /* @__PURE__ */ jsx(
|
|
240
272
|
AgentAudioVisualizerBar,
|
|
@@ -245,7 +277,8 @@ function DictationWaveform({ source, state, className }) {
|
|
|
245
277
|
barCount: 24,
|
|
246
278
|
state: state === "recording" ? "listening" : state === "transcribing" ? "thinking" : state === "requesting" ? "connecting" : "disconnected",
|
|
247
279
|
volumeBands: state === "recording" ? bands : void 0,
|
|
248
|
-
className:
|
|
280
|
+
className: "h-[64px] min-w-0 flex-1 gap-[3px] sm:h-[88px] sm:gap-[4px]",
|
|
281
|
+
children: /* @__PURE__ */ jsx("div", { className: "min-h-[4px] max-w-[6px] flex-1 rounded-full bg-current/15 transition-colors duration-200 motion-reduce:transition-none data-[lk-highlighted=true]:bg-current" })
|
|
249
282
|
}
|
|
250
283
|
);
|
|
251
284
|
}
|
package/dist/primitives/chat.cjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
var _chunk2BTDBZYNcjs = require('../chunk-2BTDBZYN.cjs');
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunkPH2TV7XIcjs = require('../chunk-PH2TV7XI.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
var _chunkYMI3X2YLcjs = require('../chunk-YMI3X2YL.cjs');
|
|
@@ -545,7 +545,7 @@ function ChatInput({
|
|
|
545
545
|
) : null,
|
|
546
546
|
(!helperText || compact) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1" }),
|
|
547
547
|
voice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
548
|
-
|
|
548
|
+
_chunkPH2TV7XIcjs.VoiceDictationButton,
|
|
549
549
|
{
|
|
550
550
|
size: "icon",
|
|
551
551
|
title: voiceTitle,
|
|
@@ -623,7 +623,7 @@ function VoiceHero({
|
|
|
623
623
|
voiceSession ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
624
624
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkYMI3X2YLcjs.VoiceSessionControls, { ...voiceSession, size: "hero" }),
|
|
625
625
|
voice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
626
|
-
|
|
626
|
+
_chunkPH2TV7XIcjs.VoiceDictationButton,
|
|
627
627
|
{
|
|
628
628
|
size: "icon",
|
|
629
629
|
title: voiceTitle,
|
|
@@ -633,7 +633,7 @@ function VoiceHero({
|
|
|
633
633
|
}
|
|
634
634
|
)
|
|
635
635
|
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
636
|
-
|
|
636
|
+
_chunkPH2TV7XIcjs.VoiceDictationButton,
|
|
637
637
|
{
|
|
638
638
|
size: "lg",
|
|
639
639
|
title: voiceTitle,
|
package/dist/primitives/chat.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
var _chunk2HTYXBDUcjs = require('../chunk-2HTYXBDU.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkAU5GUDOWcjs = require('../chunk-AU5GUDOW.cjs');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
@@ -141,7 +141,7 @@ function Connection({
|
|
|
141
141
|
),
|
|
142
142
|
children: [
|
|
143
143
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2HTYXBDUcjs.StatusBadge, { tone: s.tone, children: _nullishCoalesce(statusLabel, () => ( s.label)) }),
|
|
144
|
-
responsiveActions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
144
|
+
responsiveActions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAU5GUDOWcjs.PageHeaderActions, { actions: responsiveActions, mobileLabel: "Actions" })
|
|
145
145
|
]
|
|
146
146
|
}
|
|
147
147
|
),
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkAU5GUDOWcjs = require('../chunk-AU5GUDOW.cjs');
|
|
6
6
|
require('../chunk-ZAITUDYD.cjs');
|
|
7
7
|
require('../chunk-JDEXZGIY.cjs');
|
|
8
8
|
require('../chunk-KWLSBTB2.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
exports.PageHeaderActions =
|
|
11
|
+
exports.PageHeaderActions = _chunkAU5GUDOWcjs.PageHeaderActions;
|
|
@@ -10,7 +10,7 @@ interface PageHeaderAction {
|
|
|
10
10
|
label: ReactNode;
|
|
11
11
|
icon?: ReactNode;
|
|
12
12
|
onSelect?: () => void;
|
|
13
|
-
/** Optional nested actions.
|
|
13
|
+
/** Optional nested actions. Expanded layout renders a menu button; collapsed layout nests it inside Actions. */
|
|
14
14
|
items?: PageHeaderAction[];
|
|
15
15
|
/** Optional supporting copy shown when the action appears in a menu. */
|
|
16
16
|
description?: ReactNode;
|
|
@@ -23,7 +23,7 @@ interface PageHeaderAction {
|
|
|
23
23
|
* the button variant.
|
|
24
24
|
*/
|
|
25
25
|
priority?: "primary" | "secondary" | "tertiary";
|
|
26
|
-
/** Semantic treatment used in the collapsed
|
|
26
|
+
/** Semantic treatment used in the collapsed menu. */
|
|
27
27
|
tone?: "default" | "muted" | "destructive";
|
|
28
28
|
/** Visually separates destructive or lower-priority actions in the menu. */
|
|
29
29
|
separatorBefore?: boolean;
|
|
@@ -31,7 +31,9 @@ interface PageHeaderAction {
|
|
|
31
31
|
}
|
|
32
32
|
interface PageHeaderActionsProps {
|
|
33
33
|
actions: PageHeaderAction[];
|
|
34
|
-
/**
|
|
34
|
+
/** Responsive by default; menu keeps the same collapsed Actions menu at every width. */
|
|
35
|
+
presentation?: "responsive" | "menu";
|
|
36
|
+
/** Visible menu-trigger label, also used on desktop when presentation is menu. */
|
|
35
37
|
mobileLabel?: ReactNode;
|
|
36
38
|
/** Accessible label when `mobileLabel` is not plain text. */
|
|
37
39
|
mobileAriaLabel?: string;
|
|
@@ -42,8 +44,9 @@ interface PageHeaderActionsProps {
|
|
|
42
44
|
*
|
|
43
45
|
* Desktop keeps every action visible for fast scanning. Mobile collapses the
|
|
44
46
|
* same action definitions into one menu so page titles retain useful space.
|
|
47
|
+
* Use `presentation="menu"` to keep that menu at every viewport width.
|
|
45
48
|
* Status and other non-interactive metadata should remain beside the title.
|
|
46
49
|
*/
|
|
47
|
-
declare function PageHeaderActions({ actions, mobileLabel, mobileAriaLabel, className, }: PageHeaderActionsProps): react_jsx_runtime.JSX.Element | null;
|
|
50
|
+
declare function PageHeaderActions({ actions, presentation, mobileLabel, mobileAriaLabel, className, }: PageHeaderActionsProps): react_jsx_runtime.JSX.Element | null;
|
|
48
51
|
|
|
49
52
|
export { type PageHeaderAction, PageHeaderActions, type PageHeaderActionsProps };
|
|
@@ -10,7 +10,7 @@ interface PageHeaderAction {
|
|
|
10
10
|
label: ReactNode;
|
|
11
11
|
icon?: ReactNode;
|
|
12
12
|
onSelect?: () => void;
|
|
13
|
-
/** Optional nested actions.
|
|
13
|
+
/** Optional nested actions. Expanded layout renders a menu button; collapsed layout nests it inside Actions. */
|
|
14
14
|
items?: PageHeaderAction[];
|
|
15
15
|
/** Optional supporting copy shown when the action appears in a menu. */
|
|
16
16
|
description?: ReactNode;
|
|
@@ -23,7 +23,7 @@ interface PageHeaderAction {
|
|
|
23
23
|
* the button variant.
|
|
24
24
|
*/
|
|
25
25
|
priority?: "primary" | "secondary" | "tertiary";
|
|
26
|
-
/** Semantic treatment used in the collapsed
|
|
26
|
+
/** Semantic treatment used in the collapsed menu. */
|
|
27
27
|
tone?: "default" | "muted" | "destructive";
|
|
28
28
|
/** Visually separates destructive or lower-priority actions in the menu. */
|
|
29
29
|
separatorBefore?: boolean;
|
|
@@ -31,7 +31,9 @@ interface PageHeaderAction {
|
|
|
31
31
|
}
|
|
32
32
|
interface PageHeaderActionsProps {
|
|
33
33
|
actions: PageHeaderAction[];
|
|
34
|
-
/**
|
|
34
|
+
/** Responsive by default; menu keeps the same collapsed Actions menu at every width. */
|
|
35
|
+
presentation?: "responsive" | "menu";
|
|
36
|
+
/** Visible menu-trigger label, also used on desktop when presentation is menu. */
|
|
35
37
|
mobileLabel?: ReactNode;
|
|
36
38
|
/** Accessible label when `mobileLabel` is not plain text. */
|
|
37
39
|
mobileAriaLabel?: string;
|
|
@@ -42,8 +44,9 @@ interface PageHeaderActionsProps {
|
|
|
42
44
|
*
|
|
43
45
|
* Desktop keeps every action visible for fast scanning. Mobile collapses the
|
|
44
46
|
* same action definitions into one menu so page titles retain useful space.
|
|
47
|
+
* Use `presentation="menu"` to keep that menu at every viewport width.
|
|
45
48
|
* Status and other non-interactive metadata should remain beside the title.
|
|
46
49
|
*/
|
|
47
|
-
declare function PageHeaderActions({ actions, mobileLabel, mobileAriaLabel, className, }: PageHeaderActionsProps): react_jsx_runtime.JSX.Element | null;
|
|
50
|
+
declare function PageHeaderActions({ actions, presentation, mobileLabel, mobileAriaLabel, className, }: PageHeaderActionsProps): react_jsx_runtime.JSX.Element | null;
|
|
48
51
|
|
|
49
52
|
export { type PageHeaderAction, PageHeaderActions, type PageHeaderActionsProps };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkPH2TV7XIcjs = require('../chunk-PH2TV7XI.cjs');
|
|
6
6
|
require('../chunk-NKWHDI4C.cjs');
|
|
7
7
|
require('../chunk-JDEXZGIY.cjs');
|
|
8
8
|
require('../chunk-KWLSBTB2.cjs');
|
|
@@ -10,4 +10,4 @@ require('../chunk-2BSFYU22.cjs');
|
|
|
10
10
|
require('../chunk-7Q4EFCUI.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
exports.VoiceDictationButton =
|
|
13
|
+
exports.VoiceDictationButton = _chunkPH2TV7XIcjs.VoiceDictationButton;
|
package/package.json
CHANGED