@vvedantb/ui 0.17.1 → 0.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 +251 -3
- package/package.json +13 -5
- package/shell/src/SidebarResize.tsx +1 -4
- package/src/ai-elements/__snapshots__/queue.test.tsx.snap +11 -0
- package/src/ai-elements/activity-question-utils.ts +26 -0
- package/src/ai-elements/activity-question.tsx +159 -0
- package/src/ai-elements/activity-shared.tsx +459 -0
- package/src/ai-elements/activity-step-detail.tsx +115 -0
- package/src/ai-elements/activity-step-label.ts +981 -0
- package/src/ai-elements/activity-tasks-utils.ts +199 -0
- package/src/ai-elements/activity-tasks.tsx +770 -0
- package/src/ai-elements/artifact.tsx +162 -52
- package/src/ai-elements/attachments.tsx +62 -32
- package/src/ai-elements/code-block.tsx +76 -22
- package/src/ai-elements/context.tsx +370 -0
- package/src/ai-elements/conversation.tsx +186 -62
- package/src/ai-elements/file-chip.tsx +53 -0
- package/src/ai-elements/message.tsx +161 -50
- package/src/ai-elements/model-picker-content.tsx +505 -0
- package/src/ai-elements/model-picker-types.ts +56 -0
- package/src/ai-elements/model-picker.tsx +301 -0
- package/src/ai-elements/model-selector.tsx +102 -21
- package/src/ai-elements/plan.tsx +130 -0
- package/src/ai-elements/prompt-input-settings.tsx +144 -0
- package/src/ai-elements/prompt-input-speech.tsx +189 -0
- package/src/ai-elements/prompt-input-traits.tsx +281 -0
- package/src/ai-elements/prompt-input.tsx +320 -134
- package/src/ai-elements/provider-icon.tsx +133 -0
- package/src/ai-elements/queue.tsx +293 -9
- package/src/ai-elements/shimmer.tsx +72 -1
- package/src/ai-elements/simple-model-ladder.tsx +108 -0
- package/src/ai-elements/test-results.tsx +510 -0
- package/src/ai-elements/trace.tsx +243 -0
- package/src/ai-elements/use-streaming-disclosure.ts +50 -0
- package/src/ai-elements/web-preview.tsx +349 -0
- package/src/composer/input-area/ComposerSlashMenu.tsx +1 -1
- package/src/index.ts +66 -12
- package/src/kibo/avatar-stack.tsx +40 -0
- package/src/kibo/contribution-graph.tsx +539 -0
- package/src/kibo/cursor.tsx +72 -0
- package/src/kibo/gantt-features.tsx +439 -0
- package/src/kibo/gantt-header.tsx +181 -0
- package/src/kibo/gantt-provider.tsx +657 -0
- package/src/kibo/gantt-sidebar.tsx +157 -0
- package/src/kibo/gantt-timeline.tsx +154 -0
- package/src/kibo/index.ts +151 -0
- package/src/kibo/kanban.tsx +338 -0
- package/src/kibo/kanbanDropTarget.ts +25 -0
- package/src/kibo/list.tsx +162 -0
- package/src/kibo/theme-switcher.tsx +109 -0
- package/src/kibo/video-player.tsx +237 -0
- package/src/markdown/Markdown.tsx +112 -0
- package/src/markdown/MarkdownBlockquote.tsx +45 -0
- package/src/markdown/MarkdownCodeBlock.tsx +197 -0
- package/src/markdown/MarkdownInlineCode.tsx +40 -0
- package/src/markdown/MarkdownLink.tsx +92 -0
- package/src/markdown/codeFence.ts +57 -0
- package/src/markdown/codeHighlight.ts +138 -0
- package/src/markdown/incrementalBlocks.ts +182 -0
- package/src/markdown/index.ts +3 -0
- package/src/markdown/markdownClipboard.ts +178 -0
- package/src/markdown/mermaid.ts +155 -0
- package/src/markdown/rehypeGithubAlerts.ts +80 -0
- package/src/motion/presets.ts +24 -0
- package/src/ui/__snapshots__/alt-wrappers.test.tsx.snap +19 -0
- package/src/ui/__snapshots__/sonner-dom.test.tsx.snap +5 -0
- package/src/ui/_menu-parts.tsx +29 -0
- package/src/ui/accordion.alt.tsx +46 -53
- package/src/ui/accordion.tsx +59 -10
- package/src/ui/avatar.tsx +56 -0
- package/src/ui/badge.tsx +45 -21
- package/src/ui/border-beam.tsx +97 -0
- package/src/ui/button-group.tsx +50 -21
- package/src/ui/button.tsx +67 -45
- package/src/ui/calendar.tsx +48 -5
- package/src/ui/card.tsx +77 -8
- package/src/ui/carousel.tsx +60 -0
- package/src/ui/centered-spinner.tsx +30 -0
- package/src/ui/checkbox.tsx +34 -16
- package/src/ui/clear-input.alt.tsx +33 -75
- package/src/ui/clear-input.tsx +140 -15
- package/src/ui/collapsible.tsx +40 -2
- package/src/ui/command.tsx +143 -70
- package/src/ui/context-menu.tsx +159 -93
- package/src/ui/crossfade-icon.tsx +123 -0
- package/src/ui/dialog.tsx +154 -70
- package/src/ui/dropdown-menu.tsx +177 -117
- package/src/ui/hover-card.tsx +59 -17
- package/src/ui/input-group.alt.tsx +83 -83
- package/src/ui/input-group.tsx +129 -58
- package/src/ui/input.tsx +13 -4
- package/src/ui/label.tsx +11 -8
- package/src/ui/list-row.tsx +232 -0
- package/src/ui/loading-state.tsx +215 -0
- package/src/ui/popover.tsx +56 -23
- package/src/ui/progress.tsx +28 -16
- package/src/ui/refresh-spin-icon.tsx +41 -0
- package/src/ui/search-input.tsx +66 -15
- package/src/ui/select.tsx +171 -100
- package/src/ui/separator.tsx +23 -14
- package/src/ui/slider.tsx +21 -7
- package/src/ui/sonner.tsx +68 -30
- package/src/ui/spinner.tsx +229 -11
- package/src/ui/status-dot.tsx +84 -0
- package/src/ui/surface.tsx +49 -0
- package/src/ui/switch.tsx +29 -15
- package/src/ui/table.tsx +38 -16
- package/src/ui/tabs.tsx +123 -35
- package/src/ui/tabsSliding.ts +33 -1
- package/src/ui/textarea.tsx +13 -4
- package/src/ui/tooltip.tsx +50 -14
- package/src/ui/ui-config.tsx +149 -0
- package/src/utils/cat-color.ts +123 -0
- package/src/utils/dayjs.ts +6 -0
- package/src/utils/gesture.ts +59 -0
- package/src/utils/runtimeVisibility.ts +167 -0
- package/src/utils/sharedClock.ts +96 -0
- package/src/utils/surface-radius.ts +16 -0
- package/src/utils/useDragSensors.ts +58 -0
- package/tokens/examples/tokens-moved/Fixture.tsx +283 -0
- package/tokens/examples/tokens-moved/README.md +20 -0
- package/tokens/examples/tokens-moved/index.html +12 -0
- package/tokens/examples/tokens-moved/main.tsx +6 -0
- package/tokens/examples/tokens-moved/package.json +14 -0
- package/tokens/examples/tokens-moved/styles.css +12 -0
- package/tokens/examples/tokens-moved/tsconfig.json +14 -0
- package/tokens/examples/tokens-moved/vite.config.ts +11 -0
- package/tokens/src/css/border-beam.css +116 -0
- package/tokens/src/css/markdown.css +318 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { IconFile } from "@tabler/icons-react";
|
|
4
|
+
|
|
5
|
+
import { useCn } from "../ui/ui-config";
|
|
6
|
+
|
|
7
|
+
function FileChipLabel({
|
|
8
|
+
name,
|
|
9
|
+
className,
|
|
10
|
+
}: {
|
|
11
|
+
name: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
}) {
|
|
14
|
+
const merge = useCn();
|
|
15
|
+
return (
|
|
16
|
+
<span
|
|
17
|
+
className={merge(
|
|
18
|
+
"inline-flex w-fit max-w-full items-center gap-1.5 rounded-md border border-border bg-secondary px-1.5 py-0.5 font-mono text-xs text-foreground",
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
>
|
|
22
|
+
<IconFile className="size-3 shrink-0" />
|
|
23
|
+
<span className="truncate">{name}</span>
|
|
24
|
+
</span>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface FileChipProps {
|
|
29
|
+
name: string;
|
|
30
|
+
path?: string;
|
|
31
|
+
onOpenFile?: (path: string) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A file name in an activity line or step body. Opens the file viewer when the
|
|
36
|
+
* full path and an `onOpenFile` handler are both known; plain text otherwise.
|
|
37
|
+
*/
|
|
38
|
+
export function FileChip({ name, path, onOpenFile }: FileChipProps) {
|
|
39
|
+
if (!path || !onOpenFile) return <FileChipLabel name={name} />;
|
|
40
|
+
return (
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
title={path}
|
|
44
|
+
onClick={(event) => {
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
onOpenFile(path);
|
|
47
|
+
}}
|
|
48
|
+
className="inline-flex min-w-0 max-w-full cursor-pointer"
|
|
49
|
+
>
|
|
50
|
+
<FileChipLabel name={name} className="transition-colors hover:bg-surface-secondary" />
|
|
51
|
+
</button>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -9,62 +9,99 @@ import {
|
|
|
9
9
|
TooltipProvider,
|
|
10
10
|
TooltipTrigger,
|
|
11
11
|
} from "../ui/tooltip";
|
|
12
|
-
import {
|
|
12
|
+
import { useCn, useUiConfig } from "../ui/ui-config";
|
|
13
13
|
import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react";
|
|
14
14
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
15
|
+
/**
|
|
16
|
+
* `UiConfig.Message`: classes replace a part's built-in classes (`root`, and
|
|
17
|
+
* the `user` / `assistant` role classes of `Message`; `content` is the whole
|
|
18
|
+
* `MessageContent` list). `lazyActionTooltips` mounts a `MessageAction`
|
|
19
|
+
* tooltip on first hover or focus instead of with the button.
|
|
20
|
+
*/
|
|
21
|
+
export interface MessageConfig {
|
|
22
|
+
lazyActionTooltips?: boolean;
|
|
23
|
+
classes?: {
|
|
24
|
+
root?: string;
|
|
25
|
+
user?: string;
|
|
26
|
+
assistant?: string;
|
|
27
|
+
content?: string;
|
|
28
|
+
branchSelector?: string;
|
|
29
|
+
/** Replaces the branch arrows' `size={14}` with a class. */
|
|
30
|
+
branchIcon?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
15
33
|
export type MessageProps = HTMLAttributes<HTMLDivElement> & {
|
|
16
34
|
from: UIMessage["role"];
|
|
17
35
|
};
|
|
18
|
-
export const Message = ({ className, from, ...props }: MessageProps) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
className
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
36
|
+
export const Message = ({ className, from, ...props }: MessageProps) => {
|
|
37
|
+
const classes = useUiConfig("Message")?.classes;
|
|
38
|
+
const merge = useCn();
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
className={merge(
|
|
42
|
+
classes?.root ?? "group flex w-full max-w-[95%] flex-col gap-2",
|
|
43
|
+
from === "user"
|
|
44
|
+
? (classes?.user ?? "is-user ml-auto justify-end")
|
|
45
|
+
: (classes?.assistant ?? "is-assistant"),
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
28
52
|
export type MessageContentProps = HTMLAttributes<HTMLDivElement>;
|
|
29
53
|
export const MessageContent = ({
|
|
30
54
|
children,
|
|
31
55
|
className,
|
|
32
56
|
...props
|
|
33
|
-
}: MessageContentProps) =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
)
|
|
57
|
+
}: MessageContentProps) => {
|
|
58
|
+
const content = useUiConfig("Message")?.classes?.content;
|
|
59
|
+
const merge = useCn();
|
|
60
|
+
return (
|
|
61
|
+
<div
|
|
62
|
+
className={merge(
|
|
63
|
+
content ?? [
|
|
64
|
+
"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm",
|
|
65
|
+
"group-[.is-user]:ml-auto group-[.is-user]:rounded-2xl group-[.is-user]:rounded-br-md group-[.is-user]:bg-primary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-primary-foreground",
|
|
66
|
+
"group-[.is-assistant]:px-0 group-[.is-assistant]:text-foreground",
|
|
67
|
+
],
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
46
76
|
export type MessageActionsBarProps = ComponentProps<"div">;
|
|
47
77
|
export const MessageActionsBar = ({
|
|
48
78
|
className,
|
|
49
79
|
children,
|
|
50
80
|
...props
|
|
51
|
-
}: MessageActionsBarProps) =>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
81
|
+
}: MessageActionsBarProps) => {
|
|
82
|
+
const merge = useCn();
|
|
83
|
+
return (
|
|
84
|
+
<div className={merge("flex items-center gap-1", className)} {...props}>
|
|
85
|
+
{children}
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
56
89
|
export type MessageActionProps = ComponentProps<typeof Button> & {
|
|
57
90
|
tooltip?: string;
|
|
58
91
|
label?: string;
|
|
59
92
|
};
|
|
60
|
-
export const MessageAction = ({
|
|
93
|
+
export const MessageAction = (props: MessageActionProps) => {
|
|
94
|
+
const lazy = useUiConfig("Message")?.lazyActionTooltips;
|
|
95
|
+
return lazy ? <LazyMessageAction {...props} /> : <EagerMessageAction {...props} />;
|
|
96
|
+
};
|
|
97
|
+
function EagerMessageAction({
|
|
61
98
|
tooltip,
|
|
62
99
|
children,
|
|
63
100
|
label,
|
|
64
101
|
variant = "ghost",
|
|
65
102
|
size = "icon-sm",
|
|
66
103
|
...props
|
|
67
|
-
}: MessageActionProps)
|
|
104
|
+
}: MessageActionProps) {
|
|
68
105
|
const button = (
|
|
69
106
|
<Button size={size} type="button" variant={variant} {...props}>
|
|
70
107
|
{children}
|
|
@@ -84,7 +121,60 @@ export const MessageAction = ({
|
|
|
84
121
|
);
|
|
85
122
|
}
|
|
86
123
|
return button;
|
|
87
|
-
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The tooltip mounts on first hover or focus, not with the button. Each Radix
|
|
127
|
+
* tooltip is a dozen components plus a re-render once it has measured its
|
|
128
|
+
* anchor; a long chat has hundreds of these buttons.
|
|
129
|
+
*/
|
|
130
|
+
function LazyMessageAction({
|
|
131
|
+
tooltip,
|
|
132
|
+
children,
|
|
133
|
+
label,
|
|
134
|
+
variant = "ghost",
|
|
135
|
+
size = "icon-sm",
|
|
136
|
+
onPointerEnter,
|
|
137
|
+
onFocus,
|
|
138
|
+
...props
|
|
139
|
+
}: MessageActionProps) {
|
|
140
|
+
const [armedBy, setArmedBy] = useState<"pointer" | "focus" | null>(null);
|
|
141
|
+
const button = (
|
|
142
|
+
<Button
|
|
143
|
+
size={size}
|
|
144
|
+
type="button"
|
|
145
|
+
variant={variant}
|
|
146
|
+
onPointerEnter={(event) => {
|
|
147
|
+
onPointerEnter?.(event);
|
|
148
|
+
if (tooltip && armedBy === null) setArmedBy("pointer");
|
|
149
|
+
}}
|
|
150
|
+
onFocus={(event) => {
|
|
151
|
+
onFocus?.(event);
|
|
152
|
+
if (tooltip && armedBy === null) setArmedBy("focus");
|
|
153
|
+
}}
|
|
154
|
+
// Arming remounts the button inside the tooltip trigger; a keyboard
|
|
155
|
+
// user keeps focus on it (and so sees the tooltip).
|
|
156
|
+
autoFocus={armedBy === "focus"}
|
|
157
|
+
{...props}
|
|
158
|
+
>
|
|
159
|
+
{children}
|
|
160
|
+
<span className="sr-only">{label || tooltip}</span>
|
|
161
|
+
</Button>
|
|
162
|
+
);
|
|
163
|
+
if (tooltip && armedBy !== null) {
|
|
164
|
+
return (
|
|
165
|
+
<TooltipProvider>
|
|
166
|
+
{/* The focus that armed it landed before the tooltip existed. */}
|
|
167
|
+
<Tooltip defaultOpen={armedBy === "focus"}>
|
|
168
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
169
|
+
<TooltipContent>
|
|
170
|
+
<p>{tooltip}</p>
|
|
171
|
+
</TooltipContent>
|
|
172
|
+
</Tooltip>
|
|
173
|
+
</TooltipProvider>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
return button;
|
|
177
|
+
}
|
|
88
178
|
interface MessageBranchContextType {
|
|
89
179
|
currentBranch: number;
|
|
90
180
|
totalBranches: number;
|
|
@@ -131,6 +221,7 @@ export const MessageBranch = ({
|
|
|
131
221
|
currentBranch < branches.length - 1 ? currentBranch + 1 : 0;
|
|
132
222
|
handleBranchChange(newBranch);
|
|
133
223
|
};
|
|
224
|
+
const merge = useCn();
|
|
134
225
|
const contextValue = {
|
|
135
226
|
branches,
|
|
136
227
|
currentBranch,
|
|
@@ -142,7 +233,7 @@ export const MessageBranch = ({
|
|
|
142
233
|
return (
|
|
143
234
|
<MessageBranchContext.Provider value={contextValue}>
|
|
144
235
|
<div
|
|
145
|
-
className={
|
|
236
|
+
className={merge("grid w-full gap-2 [&>div]:pb-0", className)}
|
|
146
237
|
{...props}
|
|
147
238
|
/>
|
|
148
239
|
</MessageBranchContext.Provider>
|
|
@@ -154,6 +245,7 @@ export const MessageBranchContent = ({
|
|
|
154
245
|
...props
|
|
155
246
|
}: MessageBranchContentProps) => {
|
|
156
247
|
const { currentBranch, setBranches, branches } = useMessageBranch();
|
|
248
|
+
const merge = useCn();
|
|
157
249
|
const childrenArray = Array.isArray(children) ? children : [children];
|
|
158
250
|
useEffect(() => {
|
|
159
251
|
if (branches.length !== childrenArray.length) {
|
|
@@ -162,7 +254,7 @@ export const MessageBranchContent = ({
|
|
|
162
254
|
}, [childrenArray, branches, setBranches]);
|
|
163
255
|
return childrenArray.map((branch, index) => (
|
|
164
256
|
<div
|
|
165
|
-
className={
|
|
257
|
+
className={merge(
|
|
166
258
|
"grid gap-2 overflow-hidden [&>div]:pb-0",
|
|
167
259
|
index === currentBranch ? "block" : "hidden",
|
|
168
260
|
)}
|
|
@@ -179,13 +271,16 @@ export const MessageBranchSelector = ({
|
|
|
179
271
|
...props
|
|
180
272
|
}: MessageBranchSelectorProps) => {
|
|
181
273
|
const { totalBranches } = useMessageBranch();
|
|
274
|
+
const branchSelector = useUiConfig("Message")?.classes?.branchSelector;
|
|
275
|
+
const merge = useCn();
|
|
182
276
|
if (totalBranches <= 1) {
|
|
183
277
|
return null;
|
|
184
278
|
}
|
|
185
279
|
return (
|
|
186
280
|
<ButtonGroup
|
|
187
|
-
className={
|
|
188
|
-
|
|
281
|
+
className={merge(
|
|
282
|
+
branchSelector ??
|
|
283
|
+
"[&>*:not(:first-child)]:rounded-l-md [&>*:not(:last-child)]:rounded-r-md",
|
|
189
284
|
className,
|
|
190
285
|
)}
|
|
191
286
|
orientation="horizontal"
|
|
@@ -199,6 +294,7 @@ export const MessageBranchPrevious = ({
|
|
|
199
294
|
...props
|
|
200
295
|
}: MessageBranchPreviousProps) => {
|
|
201
296
|
const { goToPrevious, totalBranches } = useMessageBranch();
|
|
297
|
+
const branchIcon = useUiConfig("Message")?.classes?.branchIcon;
|
|
202
298
|
return (
|
|
203
299
|
<Button
|
|
204
300
|
aria-label="Previous branch"
|
|
@@ -209,7 +305,12 @@ export const MessageBranchPrevious = ({
|
|
|
209
305
|
variant="ghost"
|
|
210
306
|
{...props}
|
|
211
307
|
>
|
|
212
|
-
{children ??
|
|
308
|
+
{children ??
|
|
309
|
+
(branchIcon === undefined ? (
|
|
310
|
+
<IconChevronLeft size={14} />
|
|
311
|
+
) : (
|
|
312
|
+
<IconChevronLeft className={branchIcon} />
|
|
313
|
+
))}
|
|
213
314
|
</Button>
|
|
214
315
|
);
|
|
215
316
|
};
|
|
@@ -219,6 +320,7 @@ export const MessageBranchNext = ({
|
|
|
219
320
|
...props
|
|
220
321
|
}: MessageBranchNextProps) => {
|
|
221
322
|
const { goToNext, totalBranches } = useMessageBranch();
|
|
323
|
+
const branchIcon = useUiConfig("Message")?.classes?.branchIcon;
|
|
222
324
|
return (
|
|
223
325
|
<Button
|
|
224
326
|
aria-label="Next branch"
|
|
@@ -229,7 +331,12 @@ export const MessageBranchNext = ({
|
|
|
229
331
|
variant="ghost"
|
|
230
332
|
{...props}
|
|
231
333
|
>
|
|
232
|
-
{children ??
|
|
334
|
+
{children ??
|
|
335
|
+
(branchIcon === undefined ? (
|
|
336
|
+
<IconChevronRight size={14} />
|
|
337
|
+
) : (
|
|
338
|
+
<IconChevronRight className={branchIcon} />
|
|
339
|
+
))}
|
|
233
340
|
</Button>
|
|
234
341
|
);
|
|
235
342
|
};
|
|
@@ -239,9 +346,10 @@ export const MessageBranchPage = ({
|
|
|
239
346
|
...props
|
|
240
347
|
}: MessageBranchPageProps) => {
|
|
241
348
|
const { currentBranch, totalBranches } = useMessageBranch();
|
|
349
|
+
const merge = useCn();
|
|
242
350
|
return (
|
|
243
351
|
<ButtonGroupText
|
|
244
|
-
className={
|
|
352
|
+
className={merge(
|
|
245
353
|
"border-none bg-transparent text-muted-foreground shadow-none",
|
|
246
354
|
className,
|
|
247
355
|
)}
|
|
@@ -256,14 +364,17 @@ export const MessageToolbar = ({
|
|
|
256
364
|
className,
|
|
257
365
|
children,
|
|
258
366
|
...props
|
|
259
|
-
}: MessageToolbarProps) =>
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
className
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
367
|
+
}: MessageToolbarProps) => {
|
|
368
|
+
const merge = useCn();
|
|
369
|
+
return (
|
|
370
|
+
<div
|
|
371
|
+
className={merge(
|
|
372
|
+
"mt-4 flex w-full items-center justify-between gap-4",
|
|
373
|
+
className,
|
|
374
|
+
)}
|
|
375
|
+
{...props}
|
|
376
|
+
>
|
|
377
|
+
{children}
|
|
378
|
+
</div>
|
|
379
|
+
);
|
|
380
|
+
};
|