@mcp-b/react-components 0.11.0 → 0.12.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/dist/{AgentChat-B9LD_WF1.d.ts → AgentChat-CRmsKg9B.d.ts} +10 -6
- package/dist/{BrowserLiveView-ZktFZiMD.d.ts → BrowserLiveView-BV5qgFgI.d.ts} +11 -10
- package/dist/{BrowserReplay-6G-mnwcn.d.ts → BrowserReplay-xWvRjRAC.d.ts} +2 -1
- package/dist/{Menu-B5vDqZe_.d.ts → Menu-BLhnNnRK.d.ts} +3 -0
- package/dist/{ModelSelector-DXtpcRmT.js → ModelSelector-BB-xB-Es.js} +16 -13
- package/dist/{PromptInput-D6-G24p7.d.ts → PromptInput-IyM6ZETj.d.ts} +13 -45
- package/dist/ThinkChat-B3wYahor.js +190 -0
- package/dist/{ThinkChatActivity-B2UD95My.d.ts → ThinkChatActivity-F4KFPcJA.d.ts} +4 -4
- package/dist/ThinkChatContext-C3Eb1Xpi.d.ts +16 -0
- package/dist/{ThinkChatToolParts-DnUiZgCC.d.ts → ThinkChatToolParts-Cv4o7j6F.d.ts} +13 -5
- package/dist/components/AgentChat.d.ts +1 -1
- package/dist/components/AgentChat.js +57 -23
- package/dist/components/AgentConnection.js +4 -20
- package/dist/components/Badge.js +1 -15
- package/dist/components/BrowserLiveView.d.ts +1 -1
- package/dist/components/BrowserLiveView.js +14 -10
- package/dist/components/BrowserReplay.d.ts +1 -1
- package/dist/components/BrowserRunPanel.js +91 -55
- package/dist/components/ChatGptSignInScreen.js +1 -1
- package/dist/components/CodexModelSelector.d.ts +63 -0
- package/dist/components/CodexModelSelector.js +148 -0
- package/dist/components/Commit.d.ts +2 -2
- package/dist/components/Commit.js +10 -22
- package/dist/components/Conversation.d.ts +2 -6
- package/dist/components/Conversation.js +2 -3
- package/dist/components/EnvironmentVariables.d.ts +2 -7
- package/dist/components/EnvironmentVariables.js +10 -33
- package/dist/components/Marker.js +1 -15
- package/dist/components/McpServerPicker.d.ts +31 -6
- package/dist/components/McpServerPicker.js +129 -67
- package/dist/components/Menu.d.ts +1 -1
- package/dist/components/Menu.js +2 -2
- package/dist/components/Message.d.ts +3 -2
- package/dist/components/Message.js +10 -3
- package/dist/components/ModelSelector.d.ts +11 -8
- package/dist/components/ModelSelector.js +1 -1
- package/dist/components/PromptInput.d.ts +2 -2
- package/dist/components/PromptInput.js +49 -98
- package/dist/components/Queue.d.ts +1 -12
- package/dist/components/Reasoning.js +2 -15
- package/dist/components/Stepper.js +1 -7
- package/dist/components/ThinkChat.d.ts +30 -30
- package/dist/components/ThinkChat.js +1 -152
- package/dist/components/ThinkChatActivity.d.ts +2 -2
- package/dist/components/ThinkChatActivity.js +3 -10
- package/dist/components/ThinkChatContext.d.ts +2 -2
- package/dist/components/ThinkChatContext.js +9 -2
- package/dist/components/ThinkChatToolPanels.d.ts +1 -1
- package/dist/components/ThinkChatToolPanels.js +19 -7
- package/dist/components/ThinkChatToolParts.d.ts +1 -1
- package/dist/components/ThinkExecutionWorkbench.d.ts +10 -7
- package/dist/components/ThinkExecutionWorkbench.js +382 -359
- package/dist/components/ThinkFullApp.d.ts +16 -13
- package/dist/components/ThinkFullApp.js +28 -18
- package/dist/components/ThinkThreadPicker.d.ts +1 -31
- package/dist/components/ThinkThreadPicker.js +32 -171
- package/dist/components/ThinkThreadShell.d.ts +35 -0
- package/dist/components/ThinkThreadShell.js +146 -0
- package/dist/components/WorkspaceExplorer.js +3 -1
- package/dist/merge-refs-DF_7w2x_.js +18 -0
- package/dist/styles/agent-chat.css +4 -1
- package/dist/styles/browser-run-panel.css +57 -110
- package/dist/styles/codex-model-selector.css +197 -0
- package/dist/styles/index.css +4 -1
- package/dist/styles/mcp-server-picker.css +62 -15
- package/dist/styles/message.css +1 -1
- package/dist/styles/model-selector.css +20 -8
- package/dist/styles/prompt-input.css +5 -0
- package/dist/styles/streamdown.css +2 -48
- package/dist/styles/think-execution-workbench.css +337 -0
- package/dist/styles/think-full-app.css +15 -390
- package/dist/styles/think-resize-handle.css +33 -0
- package/dist/styles/think-thread-picker.css +0 -238
- package/dist/styles/think-thread-shell.css +219 -0
- package/dist/styles/workspace-explorer.css +8 -2
- package/dist/summarize-tool-input-BUJsENSn.js +12 -0
- package/package.json +2 -2
- package/dist/ThinkChatContext-BLAAb8J5.d.ts +0 -28
- package/dist/components/McpServerConnections.d.ts +0 -41
- package/dist/components/McpServerConnections.js +0 -188
- package/dist/components/useStickToBottom.d.ts +0 -33
- package/dist/components/useStickToBottom.js +0 -107
- package/dist/styles/mcp-server-connections.css +0 -145
|
@@ -1,41 +1,44 @@
|
|
|
1
1
|
import { WorkspaceSource } from "./WorkspaceExplorer.js";
|
|
2
2
|
import { ThinkChatMessagesProps } from "./ThinkChat.js";
|
|
3
|
-
import { ThinkExecutionAgent, ThinkExecutionWorkbench, ThinkExecutionWorkbenchProps, ThinkExecutionWorkbenchSource } from "./ThinkExecutionWorkbench.js";
|
|
4
3
|
import * as React from "react";
|
|
5
4
|
import { useAgentChat } from "@cloudflare/think/react";
|
|
6
5
|
import { UIMessage } from "ai";
|
|
7
6
|
import { useAgent } from "agents/react";
|
|
8
7
|
import { Think } from "@cloudflare/think";
|
|
9
8
|
|
|
9
|
+
//#region src/components/_internal/think-agent.d.ts
|
|
10
|
+
/** Shared complete Think specialization for stateful React agent hooks. */
|
|
11
|
+
type ThinkAgent<State = unknown> = Think<object, State>;
|
|
12
|
+
//#endregion
|
|
10
13
|
//#region src/components/ThinkFullApp.d.ts
|
|
11
|
-
type ThinkFullAppAgent<State = unknown> =
|
|
14
|
+
type ThinkFullAppAgent<State = unknown> = ThinkAgent<State>;
|
|
12
15
|
type ThinkFullAppWorkbenchView = "files" | "execution" | (string & {});
|
|
13
|
-
interface ThinkFullAppPanelContext<AgentT extends ThinkFullAppAgent<State>, State = unknown> {
|
|
16
|
+
interface ThinkFullAppPanelContext<AgentT extends ThinkFullAppAgent<State>, State = unknown, MessageT extends UIMessage = UIMessage> {
|
|
14
17
|
agent: ReturnType<typeof useAgent<AgentT, State>>;
|
|
15
|
-
chat: ReturnType<typeof useAgentChat<State,
|
|
18
|
+
chat: ReturnType<typeof useAgentChat<State, MessageT>>;
|
|
16
19
|
workspace?: WorkspaceSource;
|
|
17
20
|
workspaceRoot?: string;
|
|
18
21
|
}
|
|
19
|
-
interface ThinkFullAppPanel<AgentT extends ThinkFullAppAgent<State>, State = unknown> {
|
|
22
|
+
interface ThinkFullAppPanel<AgentT extends ThinkFullAppAgent<State>, State = unknown, MessageT extends UIMessage = UIMessage> {
|
|
20
23
|
/** Unique panel id used by `workbenchView`; custom panels should not reuse built-in ids. */
|
|
21
24
|
id: ThinkFullAppWorkbenchView;
|
|
22
25
|
label: string;
|
|
23
26
|
icon: React.ReactNode;
|
|
24
|
-
render: (context: ThinkFullAppPanelContext<AgentT, State>) => React.ReactNode;
|
|
27
|
+
render: (context: ThinkFullAppPanelContext<AgentT, State, MessageT>) => React.ReactNode;
|
|
25
28
|
}
|
|
26
|
-
interface ThinkFullAppProps<AgentT extends ThinkFullAppAgent<State>, State = unknown> extends React.HTMLAttributes<HTMLDivElement> {
|
|
29
|
+
interface ThinkFullAppProps<AgentT extends ThinkFullAppAgent<State>, State = unknown, MessageT extends UIMessage = UIMessage> extends React.HTMLAttributes<HTMLDivElement> {
|
|
27
30
|
/** The `useAgent` value from `agents/react`; its stub drives approvals and execution records. */
|
|
28
31
|
agent: ReturnType<typeof useAgent<AgentT, State>>;
|
|
29
32
|
/** The `useAgentChat` value from `@cloudflare/think/react` used by the chat surface. */
|
|
30
|
-
chat: ReturnType<typeof useAgentChat<State,
|
|
33
|
+
chat: ReturnType<typeof useAgentChat<State, MessageT>>;
|
|
31
34
|
/** Optional workspace source shown in the file explorer pane. */
|
|
32
35
|
workspace?: WorkspaceSource;
|
|
33
36
|
/** Root path passed to the workspace explorer. */
|
|
34
37
|
workspaceRoot?: string;
|
|
35
38
|
/** Message rendering labels and approval overrides for ThinkChat. */
|
|
36
|
-
messages?: ThinkChatMessagesProps
|
|
39
|
+
messages?: ThinkChatMessagesProps<MessageT>;
|
|
37
40
|
/** Extra workbench panels appended after the built-in Files and Execution panels. */
|
|
38
|
-
workbenchPanels?: readonly ThinkFullAppPanel<AgentT, State>[];
|
|
41
|
+
workbenchPanels?: readonly ThinkFullAppPanel<AgentT, State, MessageT>[];
|
|
39
42
|
/** Optional parent-owned thread picker/sidebar rendered beside the selected child app. */
|
|
40
43
|
threadSidebar?: React.ReactNode;
|
|
41
44
|
/** Whether the thread sidebar is open. Omit for internal state. */
|
|
@@ -52,7 +55,7 @@ interface ThinkFullAppProps<AgentT extends ThinkFullAppAgent<State>, State = unk
|
|
|
52
55
|
onWorkbenchViewChange?: (view: ThinkFullAppWorkbenchView) => void;
|
|
53
56
|
}
|
|
54
57
|
/** Combines ThinkChat with an optional resizable workbench shell. */
|
|
55
|
-
declare function ThinkFullApp<AgentT extends ThinkFullAppAgent<State>, State = unknown>({
|
|
58
|
+
declare function ThinkFullApp<AgentT extends ThinkFullAppAgent<State>, State = unknown, MessageT extends UIMessage = UIMessage>({
|
|
56
59
|
agent,
|
|
57
60
|
chat,
|
|
58
61
|
className,
|
|
@@ -70,8 +73,8 @@ declare function ThinkFullApp<AgentT extends ThinkFullAppAgent<State>, State = u
|
|
|
70
73
|
workspace,
|
|
71
74
|
workspaceRoot,
|
|
72
75
|
...props
|
|
73
|
-
}: ThinkFullAppProps<AgentT, State> & {
|
|
76
|
+
}: ThinkFullAppProps<AgentT, State, MessageT> & {
|
|
74
77
|
ref?: React.Ref<HTMLDivElement>;
|
|
75
78
|
}): React.JSX.Element;
|
|
76
79
|
//#endregion
|
|
77
|
-
export {
|
|
80
|
+
export { ThinkFullApp, ThinkFullAppAgent, ThinkFullAppPanel, ThinkFullAppPanelContext, ThinkFullAppProps, ThinkFullAppWorkbenchView };
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
2
|
import { P as TerminalIcon, h as FileIcon, n as ArrowLeftIcon } from "../icons-D2Q5n5C1.js";
|
|
3
|
+
import { Separator } from "./Separator.js";
|
|
3
4
|
import { Button } from "./Button.js";
|
|
4
5
|
import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
|
|
5
6
|
import { ToggleGroup, ToggleGroupItem } from "./ToggleGroup.js";
|
|
7
|
+
import { o as useThinkPendingApprovals, s as resolveThinkApprovalProps, t as ThinkChat } from "../ThinkChat-B3wYahor.js";
|
|
6
8
|
import { WorkspaceExplorer, useWorkspace } from "./WorkspaceExplorer.js";
|
|
7
|
-
import { ThinkChat, useThinkPendingApprovals } from "./ThinkChat.js";
|
|
8
9
|
import { ThinkExecutionWorkbench } from "./ThinkExecutionWorkbench.js";
|
|
9
|
-
import { ThinkThreadShell } from "./
|
|
10
|
+
import { ThinkThreadShell } from "./ThinkThreadShell.js";
|
|
10
11
|
import * as React from "react";
|
|
11
12
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
13
|
//#region src/components/ThinkFullApp.tsx
|
|
@@ -27,9 +28,9 @@ function beginWorkbenchPanelResize(event, current, apply) {
|
|
|
27
28
|
window.removeEventListener("pointermove", onMove);
|
|
28
29
|
window.removeEventListener("pointerup", onUp);
|
|
29
30
|
window.removeEventListener("pointercancel", onUp);
|
|
30
|
-
document.body.classList.remove("is-resizing-
|
|
31
|
+
document.body.classList.remove("is-resizing-think-full-app");
|
|
31
32
|
};
|
|
32
|
-
document.body.classList.add("is-resizing-
|
|
33
|
+
document.body.classList.add("is-resizing-think-full-app");
|
|
33
34
|
window.addEventListener("pointermove", onMove);
|
|
34
35
|
window.addEventListener("pointerup", onUp);
|
|
35
36
|
window.addEventListener("pointercancel", onUp);
|
|
@@ -88,13 +89,24 @@ function WorkbenchViewSwitch({ panels, value, onValueChange }) {
|
|
|
88
89
|
/** Combines ThinkChat with an optional resizable workbench shell. */
|
|
89
90
|
function ThinkFullApp({ agent, chat, className, defaultWorkbenchView, defaultThreadSidebarOpen, messages, onThreadSidebarOpenChange, onWorkbenchViewChange, ref, style, threadSidebar, threadSidebarOpen, workbenchPanels, workbenchView, workspace, workspaceRoot, ...props }) {
|
|
90
91
|
const approvals = useThinkPendingApprovals(agent.stub, `${chat.messages.length}:${chat.status}`);
|
|
91
|
-
const resolvedMessages = React.useMemo(() =>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
const resolvedMessages = React.useMemo(() => {
|
|
93
|
+
const approvalProps = resolveThinkApprovalProps({
|
|
94
|
+
thinkStub: messages?.thinkStub,
|
|
95
|
+
pendingApprovals: messages?.pendingApprovals,
|
|
96
|
+
onExecutionSettled: messages?.onExecutionSettled
|
|
97
|
+
}, {
|
|
98
|
+
thinkStub: agent.stub,
|
|
99
|
+
pendingApprovals: approvals.pendingApprovals,
|
|
100
|
+
onExecutionSettled: approvals.refreshPendingApprovals
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
...messages,
|
|
104
|
+
...approvalProps
|
|
105
|
+
};
|
|
106
|
+
}, [
|
|
107
|
+
agent.stub,
|
|
97
108
|
approvals.pendingApprovals,
|
|
109
|
+
approvals.refreshPendingApprovals,
|
|
98
110
|
messages
|
|
99
111
|
]);
|
|
100
112
|
const [mobileView, setMobileView] = React.useState("chat");
|
|
@@ -160,9 +172,7 @@ function ThinkFullApp({ agent, chat, className, defaultWorkbenchView, defaultThr
|
|
|
160
172
|
const app = /* @__PURE__ */ jsxs("div", {
|
|
161
173
|
ref,
|
|
162
174
|
className: cx("think-full-app", className),
|
|
163
|
-
"data-has-files": hasWorkspace ? "true" : "false",
|
|
164
175
|
"data-has-thread-sidebar": threadSidebar ? "true" : "false",
|
|
165
|
-
"data-has-workbench": "true",
|
|
166
176
|
"data-has-workbench-topbar": showWorkbenchViewSwitch ? "true" : "false",
|
|
167
177
|
"data-mobile-view": activeMobileView,
|
|
168
178
|
style: rootStyle,
|
|
@@ -220,15 +230,15 @@ function ThinkFullApp({ agent, chat, className, defaultWorkbenchView, defaultThr
|
|
|
220
230
|
})
|
|
221
231
|
})
|
|
222
232
|
}),
|
|
223
|
-
/* @__PURE__ */ jsx(
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
/* @__PURE__ */ jsx(Separator, {
|
|
234
|
+
decorative: false,
|
|
235
|
+
orientation: "vertical",
|
|
236
|
+
tabIndex: 0,
|
|
226
237
|
"aria-label": "Resize workbench panel",
|
|
227
|
-
"aria-orientation": "vertical",
|
|
228
238
|
"aria-valuemin": workbenchPanelMinWidth,
|
|
229
239
|
"aria-valuemax": workbenchPanelMaxWidth,
|
|
230
240
|
"aria-valuenow": workbenchPanelWidth,
|
|
231
|
-
className: "think-full-app__resizer",
|
|
241
|
+
className: "think-resize-handle think-full-app__resizer",
|
|
232
242
|
onPointerDown: (event) => beginWorkbenchPanelResize(event, workbenchPanelWidth, setWorkbenchPanelWidth),
|
|
233
243
|
onKeyDown: (event) => {
|
|
234
244
|
if (event.key === "ArrowLeft") {
|
|
@@ -270,4 +280,4 @@ function ThinkFullApp({ agent, chat, className, defaultWorkbenchView, defaultThr
|
|
|
270
280
|
});
|
|
271
281
|
}
|
|
272
282
|
//#endregion
|
|
273
|
-
export {
|
|
283
|
+
export { ThinkFullApp };
|
|
@@ -33,16 +33,6 @@ interface ThinkThreadPickerProps extends Omit<React.HTMLAttributes<HTMLElement>,
|
|
|
33
33
|
/** Accessible label for the list navigation. */
|
|
34
34
|
"aria-label"?: string;
|
|
35
35
|
}
|
|
36
|
-
interface ThinkThreadShellProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
37
|
-
/** Thread picker or app-owned sidebar shown beside the selected child shell. */
|
|
38
|
-
sidebar: React.ReactNode;
|
|
39
|
-
/** Whether the thread drawer is open. Omit for internal state. */
|
|
40
|
-
sidebarOpen?: boolean;
|
|
41
|
-
/** Initial thread drawer state when `sidebarOpen` is uncontrolled. */
|
|
42
|
-
defaultSidebarOpen?: boolean;
|
|
43
|
-
/** Called when the thread drawer is opened or closed. */
|
|
44
|
-
onSidebarOpenChange?: (open: boolean) => void;
|
|
45
|
-
}
|
|
46
36
|
/**
|
|
47
37
|
* Thread roster UI for sub-agent chat apps.
|
|
48
38
|
*
|
|
@@ -64,25 +54,5 @@ declare function ThinkThreadPicker({
|
|
|
64
54
|
}: ThinkThreadPickerProps & {
|
|
65
55
|
ref?: React.Ref<HTMLElement>;
|
|
66
56
|
}): React.JSX.Element;
|
|
67
|
-
/**
|
|
68
|
-
* Layout wrapper for a thread picker beside one selected `ThinkFullApp`.
|
|
69
|
-
*
|
|
70
|
-
* Mobile keeps the drawer at about 80% width so the selected chat remains
|
|
71
|
-
* visible as a preview. It only owns layout; callers still own the parent agent,
|
|
72
|
-
* selected child agent, chat hook, and shared workspace.
|
|
73
|
-
*/
|
|
74
|
-
declare function ThinkThreadShell({
|
|
75
|
-
sidebar,
|
|
76
|
-
sidebarOpen,
|
|
77
|
-
defaultSidebarOpen,
|
|
78
|
-
onSidebarOpenChange,
|
|
79
|
-
className,
|
|
80
|
-
children,
|
|
81
|
-
ref,
|
|
82
|
-
style,
|
|
83
|
-
...props
|
|
84
|
-
}: ThinkThreadShellProps & {
|
|
85
|
-
ref?: React.Ref<HTMLDivElement>;
|
|
86
|
-
}): React.JSX.Element;
|
|
87
57
|
//#endregion
|
|
88
|
-
export { ThinkThreadItem, ThinkThreadPicker, ThinkThreadPickerProps
|
|
58
|
+
export { ThinkThreadItem, ThinkThreadPicker, ThinkThreadPickerProps };
|
|
@@ -1,42 +1,10 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
-
import { M as SpinnerIcon, O as PlusIcon,
|
|
2
|
+
import { M as SpinnerIcon, O as PlusIcon, u as DotIcon } from "../icons-D2Q5n5C1.js";
|
|
3
3
|
import { Button } from "./Button.js";
|
|
4
|
-
import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
|
|
5
4
|
import { ScrollArea } from "./ScrollArea.js";
|
|
6
|
-
import
|
|
5
|
+
import "react";
|
|
7
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
7
|
//#region src/components/ThinkThreadPicker.tsx
|
|
9
|
-
const threadSidebarDefaultWidth = 256;
|
|
10
|
-
const threadSidebarMinWidth = 224;
|
|
11
|
-
const threadSidebarMaxWidth = 384;
|
|
12
|
-
const threadSidebarKeyboardStep = 24;
|
|
13
|
-
function useControllableSidebar({ sidebarOpen, defaultSidebarOpen, onSidebarOpenChange }) {
|
|
14
|
-
const [innerOpen, setInnerOpen] = React.useState(defaultSidebarOpen ?? true);
|
|
15
|
-
return [sidebarOpen ?? innerOpen, React.useCallback((next) => {
|
|
16
|
-
if (sidebarOpen === void 0) setInnerOpen(next);
|
|
17
|
-
onSidebarOpenChange?.(next);
|
|
18
|
-
}, [sidebarOpen, onSidebarOpenChange])];
|
|
19
|
-
}
|
|
20
|
-
function clampThreadSidebarWidth(width) {
|
|
21
|
-
return Math.min(threadSidebarMaxWidth, Math.max(threadSidebarMinWidth, width));
|
|
22
|
-
}
|
|
23
|
-
function beginThreadSidebarResize(event, current, apply) {
|
|
24
|
-
event.preventDefault();
|
|
25
|
-
const startX = event.clientX;
|
|
26
|
-
const onMove = (move) => {
|
|
27
|
-
apply(clampThreadSidebarWidth(current + move.clientX - startX));
|
|
28
|
-
};
|
|
29
|
-
const onUp = () => {
|
|
30
|
-
window.removeEventListener("pointermove", onMove);
|
|
31
|
-
window.removeEventListener("pointerup", onUp);
|
|
32
|
-
window.removeEventListener("pointercancel", onUp);
|
|
33
|
-
document.body.classList.remove("is-resizing-columns");
|
|
34
|
-
};
|
|
35
|
-
document.body.classList.add("is-resizing-columns");
|
|
36
|
-
window.addEventListener("pointermove", onMove);
|
|
37
|
-
window.addEventListener("pointerup", onUp);
|
|
38
|
-
window.addEventListener("pointercancel", onUp);
|
|
39
|
-
}
|
|
40
8
|
function toThreadDate(value) {
|
|
41
9
|
if (value === void 0) return void 0;
|
|
42
10
|
const date = value instanceof Date ? value : new Date(value);
|
|
@@ -116,38 +84,35 @@ function ThinkThreadPicker({ threads, selectedId, onSelect, onCreate, className,
|
|
|
116
84
|
const timestamp = formatThreadTimestamp(thread);
|
|
117
85
|
const statusLabel = formatThreadStatus(thread);
|
|
118
86
|
const busy = isThreadBusy(thread.status);
|
|
119
|
-
return /* @__PURE__ */ jsx("li", {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
children:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}) : null]
|
|
149
|
-
})
|
|
150
|
-
}, thread.id);
|
|
87
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(Button, {
|
|
88
|
+
type: "button",
|
|
89
|
+
variant: "ghost",
|
|
90
|
+
color: "neutral",
|
|
91
|
+
size: "sm",
|
|
92
|
+
className: "think-thread-picker__thread",
|
|
93
|
+
"data-selected": thread.id === selectedId ? "true" : "false",
|
|
94
|
+
"data-status": thread.status,
|
|
95
|
+
"aria-current": thread.id === selectedId ? "page" : void 0,
|
|
96
|
+
onClick: () => onSelect(thread.id),
|
|
97
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
98
|
+
className: "think-thread-picker__thread-title",
|
|
99
|
+
children: thread.title
|
|
100
|
+
}), statusLabel ? /* @__PURE__ */ jsx("span", {
|
|
101
|
+
className: "think-thread-picker__thread-status",
|
|
102
|
+
role: "img",
|
|
103
|
+
"aria-label": statusLabel,
|
|
104
|
+
title: statusLabel,
|
|
105
|
+
children: busy ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : /* @__PURE__ */ jsx(DotIcon, {})
|
|
106
|
+
}) : timestamp?.date ? /* @__PURE__ */ jsx("time", {
|
|
107
|
+
className: "think-thread-picker__thread-time",
|
|
108
|
+
dateTime: timestamp.date.toISOString(),
|
|
109
|
+
title: timestamp.date.toLocaleString(),
|
|
110
|
+
children: timestamp.label
|
|
111
|
+
}) : timestamp ? /* @__PURE__ */ jsx("span", {
|
|
112
|
+
className: "think-thread-picker__thread-time",
|
|
113
|
+
children: timestamp.label
|
|
114
|
+
}) : null]
|
|
115
|
+
}) }, thread.id);
|
|
151
116
|
})
|
|
152
117
|
}) : /* @__PURE__ */ jsx("p", {
|
|
153
118
|
className: "think-thread-picker__empty",
|
|
@@ -174,109 +139,5 @@ function ThinkThreadPicker({ threads, selectedId, onSelect, onCreate, className,
|
|
|
174
139
|
]
|
|
175
140
|
});
|
|
176
141
|
}
|
|
177
|
-
/**
|
|
178
|
-
* Layout wrapper for a thread picker beside one selected `ThinkFullApp`.
|
|
179
|
-
*
|
|
180
|
-
* Mobile keeps the drawer at about 80% width so the selected chat remains
|
|
181
|
-
* visible as a preview. It only owns layout; callers still own the parent agent,
|
|
182
|
-
* selected child agent, chat hook, and shared workspace.
|
|
183
|
-
*/
|
|
184
|
-
function ThinkThreadShell({ sidebar, sidebarOpen, defaultSidebarOpen, onSidebarOpenChange, className, children, ref, style, ...props }) {
|
|
185
|
-
const sidebarId = React.useId();
|
|
186
|
-
const [isSidebarOpen, setSidebarOpen] = useControllableSidebar({
|
|
187
|
-
sidebarOpen,
|
|
188
|
-
defaultSidebarOpen,
|
|
189
|
-
onSidebarOpenChange
|
|
190
|
-
});
|
|
191
|
-
const [sidebarWidth, setSidebarWidth] = React.useState(threadSidebarDefaultWidth);
|
|
192
|
-
const toggleLabel = isSidebarOpen ? "Hide threads" : "Show threads";
|
|
193
|
-
const rootStyle = {
|
|
194
|
-
...style,
|
|
195
|
-
"--think-thread-sidebar-w": `${sidebarWidth}px`
|
|
196
|
-
};
|
|
197
|
-
const resizeThreadSidebarBy = (delta) => {
|
|
198
|
-
setSidebarWidth((current) => clampThreadSidebarWidth(current + delta));
|
|
199
|
-
};
|
|
200
|
-
return /* @__PURE__ */ jsx("div", {
|
|
201
|
-
ref,
|
|
202
|
-
className: cx("think-thread-shell", className),
|
|
203
|
-
style: rootStyle,
|
|
204
|
-
...props,
|
|
205
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
206
|
-
className: "think-thread-shell__frame",
|
|
207
|
-
"data-sidebar-open": isSidebarOpen ? "true" : "false",
|
|
208
|
-
children: [
|
|
209
|
-
/* @__PURE__ */ jsx("div", {
|
|
210
|
-
className: "think-thread-shell__toolbar",
|
|
211
|
-
role: "toolbar",
|
|
212
|
-
"aria-label": "Thread controls",
|
|
213
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
214
|
-
className: "think-thread-shell__panel-toggle",
|
|
215
|
-
children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button, {
|
|
216
|
-
type: "button",
|
|
217
|
-
variant: "ghost",
|
|
218
|
-
color: "neutral",
|
|
219
|
-
size: "icon",
|
|
220
|
-
"aria-label": toggleLabel,
|
|
221
|
-
"aria-controls": sidebarId,
|
|
222
|
-
"aria-expanded": isSidebarOpen,
|
|
223
|
-
"aria-pressed": isSidebarOpen,
|
|
224
|
-
"data-selected": isSidebarOpen,
|
|
225
|
-
onClick: () => setSidebarOpen(!isSidebarOpen),
|
|
226
|
-
children: /* @__PURE__ */ jsx(SidebarIcon, {})
|
|
227
|
-
}) }), /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, {
|
|
228
|
-
side: "bottom",
|
|
229
|
-
sideOffset: 6,
|
|
230
|
-
children: /* @__PURE__ */ jsx(TooltipPopup, { children: toggleLabel })
|
|
231
|
-
}) })] })
|
|
232
|
-
})
|
|
233
|
-
}),
|
|
234
|
-
isSidebarOpen ? /* @__PURE__ */ jsx("button", {
|
|
235
|
-
type: "button",
|
|
236
|
-
role: "separator",
|
|
237
|
-
"aria-label": "Resize threads panel",
|
|
238
|
-
"aria-orientation": "vertical",
|
|
239
|
-
"aria-valuemin": threadSidebarMinWidth,
|
|
240
|
-
"aria-valuemax": threadSidebarMaxWidth,
|
|
241
|
-
"aria-valuenow": sidebarWidth,
|
|
242
|
-
className: "think-thread-shell__resizer",
|
|
243
|
-
onPointerDown: (event) => beginThreadSidebarResize(event, sidebarWidth, setSidebarWidth),
|
|
244
|
-
onKeyDown: (event) => {
|
|
245
|
-
if (event.key === "ArrowLeft") {
|
|
246
|
-
event.preventDefault();
|
|
247
|
-
resizeThreadSidebarBy(-24);
|
|
248
|
-
} else if (event.key === "ArrowRight") {
|
|
249
|
-
event.preventDefault();
|
|
250
|
-
resizeThreadSidebarBy(threadSidebarKeyboardStep);
|
|
251
|
-
} else if (event.key === "Home") {
|
|
252
|
-
event.preventDefault();
|
|
253
|
-
setSidebarWidth(threadSidebarMinWidth);
|
|
254
|
-
} else if (event.key === "End") {
|
|
255
|
-
event.preventDefault();
|
|
256
|
-
setSidebarWidth(threadSidebarMaxWidth);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}) : null,
|
|
260
|
-
/* @__PURE__ */ jsx("div", {
|
|
261
|
-
id: sidebarId,
|
|
262
|
-
className: "think-thread-shell__sidebar",
|
|
263
|
-
"aria-hidden": isSidebarOpen ? void 0 : true,
|
|
264
|
-
inert: isSidebarOpen ? void 0 : true,
|
|
265
|
-
children: sidebar
|
|
266
|
-
}),
|
|
267
|
-
/* @__PURE__ */ jsx("div", {
|
|
268
|
-
className: "think-thread-shell__main",
|
|
269
|
-
children
|
|
270
|
-
}),
|
|
271
|
-
isSidebarOpen ? /* @__PURE__ */ jsx("button", {
|
|
272
|
-
type: "button",
|
|
273
|
-
className: "think-thread-shell__peek",
|
|
274
|
-
"aria-label": "Show selected thread",
|
|
275
|
-
onClick: () => setSidebarOpen(false)
|
|
276
|
-
}) : null
|
|
277
|
-
]
|
|
278
|
-
})
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
142
|
//#endregion
|
|
282
|
-
export { ThinkThreadPicker
|
|
143
|
+
export { ThinkThreadPicker };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/components/ThinkThreadShell.d.ts
|
|
4
|
+
interface ThinkThreadShellProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
/** Thread picker or app-owned sidebar shown beside the selected child shell. */
|
|
6
|
+
sidebar: React.ReactNode;
|
|
7
|
+
/** Whether the thread drawer is open. Omit for internal state. */
|
|
8
|
+
sidebarOpen?: boolean;
|
|
9
|
+
/** Initial thread drawer state when `sidebarOpen` is uncontrolled. */
|
|
10
|
+
defaultSidebarOpen?: boolean;
|
|
11
|
+
/** Called when the thread drawer is opened or closed. */
|
|
12
|
+
onSidebarOpenChange?: (open: boolean) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Layout wrapper for a thread picker beside one selected `ThinkFullApp`.
|
|
16
|
+
*
|
|
17
|
+
* Mobile keeps the drawer at about 80% width so the selected chat remains
|
|
18
|
+
* visible as a preview. It only owns layout; callers still own the parent agent,
|
|
19
|
+
* selected child agent, chat hook, and shared workspace.
|
|
20
|
+
*/
|
|
21
|
+
declare function ThinkThreadShell({
|
|
22
|
+
sidebar,
|
|
23
|
+
sidebarOpen,
|
|
24
|
+
defaultSidebarOpen,
|
|
25
|
+
onSidebarOpenChange,
|
|
26
|
+
className,
|
|
27
|
+
children,
|
|
28
|
+
ref,
|
|
29
|
+
style,
|
|
30
|
+
...props
|
|
31
|
+
}: ThinkThreadShellProps & {
|
|
32
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
33
|
+
}): React.JSX.Element;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { ThinkThreadShell, ThinkThreadShellProps };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
+
import { j as SidebarIcon } from "../icons-D2Q5n5C1.js";
|
|
3
|
+
import { Separator } from "./Separator.js";
|
|
4
|
+
import { Button } from "./Button.js";
|
|
5
|
+
import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/components/ThinkThreadShell.tsx
|
|
9
|
+
const threadSidebarDefaultWidth = 256;
|
|
10
|
+
const threadSidebarMinWidth = 224;
|
|
11
|
+
const threadSidebarMaxWidth = 384;
|
|
12
|
+
const threadSidebarKeyboardStep = 24;
|
|
13
|
+
function useControllableSidebar({ sidebarOpen, defaultSidebarOpen, onSidebarOpenChange }) {
|
|
14
|
+
const [innerOpen, setInnerOpen] = React.useState(defaultSidebarOpen ?? true);
|
|
15
|
+
return [sidebarOpen ?? innerOpen, React.useCallback((next) => {
|
|
16
|
+
if (sidebarOpen === void 0) setInnerOpen(next);
|
|
17
|
+
onSidebarOpenChange?.(next);
|
|
18
|
+
}, [sidebarOpen, onSidebarOpenChange])];
|
|
19
|
+
}
|
|
20
|
+
function clampThreadSidebarWidth(width) {
|
|
21
|
+
return Math.min(threadSidebarMaxWidth, Math.max(threadSidebarMinWidth, width));
|
|
22
|
+
}
|
|
23
|
+
function beginThreadSidebarResize(event, current, apply) {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
const startX = event.clientX;
|
|
26
|
+
const onMove = (move) => {
|
|
27
|
+
apply(clampThreadSidebarWidth(current + move.clientX - startX));
|
|
28
|
+
};
|
|
29
|
+
const onUp = () => {
|
|
30
|
+
window.removeEventListener("pointermove", onMove);
|
|
31
|
+
window.removeEventListener("pointerup", onUp);
|
|
32
|
+
window.removeEventListener("pointercancel", onUp);
|
|
33
|
+
document.body.classList.remove("is-resizing-think-thread-shell");
|
|
34
|
+
};
|
|
35
|
+
document.body.classList.add("is-resizing-think-thread-shell");
|
|
36
|
+
window.addEventListener("pointermove", onMove);
|
|
37
|
+
window.addEventListener("pointerup", onUp);
|
|
38
|
+
window.addEventListener("pointercancel", onUp);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Layout wrapper for a thread picker beside one selected `ThinkFullApp`.
|
|
42
|
+
*
|
|
43
|
+
* Mobile keeps the drawer at about 80% width so the selected chat remains
|
|
44
|
+
* visible as a preview. It only owns layout; callers still own the parent agent,
|
|
45
|
+
* selected child agent, chat hook, and shared workspace.
|
|
46
|
+
*/
|
|
47
|
+
function ThinkThreadShell({ sidebar, sidebarOpen, defaultSidebarOpen, onSidebarOpenChange, className, children, ref, style, ...props }) {
|
|
48
|
+
const sidebarId = React.useId();
|
|
49
|
+
const [isSidebarOpen, setSidebarOpen] = useControllableSidebar({
|
|
50
|
+
sidebarOpen,
|
|
51
|
+
defaultSidebarOpen,
|
|
52
|
+
onSidebarOpenChange
|
|
53
|
+
});
|
|
54
|
+
const [sidebarWidth, setSidebarWidth] = React.useState(threadSidebarDefaultWidth);
|
|
55
|
+
const toggleLabel = isSidebarOpen ? "Hide threads" : "Show threads";
|
|
56
|
+
const rootStyle = {
|
|
57
|
+
...style,
|
|
58
|
+
"--think-thread-sidebar-w": `${sidebarWidth}px`
|
|
59
|
+
};
|
|
60
|
+
const resizeThreadSidebarBy = (delta) => {
|
|
61
|
+
setSidebarWidth((current) => clampThreadSidebarWidth(current + delta));
|
|
62
|
+
};
|
|
63
|
+
return /* @__PURE__ */ jsx("div", {
|
|
64
|
+
ref,
|
|
65
|
+
className: cx("think-thread-shell", className),
|
|
66
|
+
style: rootStyle,
|
|
67
|
+
...props,
|
|
68
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
69
|
+
className: "think-thread-shell__frame",
|
|
70
|
+
"data-sidebar-open": isSidebarOpen ? "true" : "false",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx("div", {
|
|
73
|
+
className: "think-thread-shell__toolbar",
|
|
74
|
+
role: "toolbar",
|
|
75
|
+
"aria-label": "Thread controls",
|
|
76
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
77
|
+
className: "think-thread-shell__panel-toggle",
|
|
78
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button, {
|
|
79
|
+
type: "button",
|
|
80
|
+
variant: "ghost",
|
|
81
|
+
color: "neutral",
|
|
82
|
+
size: "icon",
|
|
83
|
+
"aria-label": toggleLabel,
|
|
84
|
+
"aria-controls": sidebarId,
|
|
85
|
+
"aria-expanded": isSidebarOpen,
|
|
86
|
+
"aria-pressed": isSidebarOpen,
|
|
87
|
+
"data-selected": isSidebarOpen,
|
|
88
|
+
onClick: () => setSidebarOpen(!isSidebarOpen),
|
|
89
|
+
children: /* @__PURE__ */ jsx(SidebarIcon, {})
|
|
90
|
+
}) }), /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, {
|
|
91
|
+
side: "bottom",
|
|
92
|
+
sideOffset: 6,
|
|
93
|
+
children: /* @__PURE__ */ jsx(TooltipPopup, { children: toggleLabel })
|
|
94
|
+
}) })] })
|
|
95
|
+
})
|
|
96
|
+
}),
|
|
97
|
+
isSidebarOpen ? /* @__PURE__ */ jsx(Separator, {
|
|
98
|
+
decorative: false,
|
|
99
|
+
orientation: "vertical",
|
|
100
|
+
tabIndex: 0,
|
|
101
|
+
"aria-label": "Resize threads panel",
|
|
102
|
+
"aria-valuemin": threadSidebarMinWidth,
|
|
103
|
+
"aria-valuemax": threadSidebarMaxWidth,
|
|
104
|
+
"aria-valuenow": sidebarWidth,
|
|
105
|
+
className: "think-resize-handle think-thread-shell__resizer",
|
|
106
|
+
onPointerDown: (event) => beginThreadSidebarResize(event, sidebarWidth, setSidebarWidth),
|
|
107
|
+
onKeyDown: (event) => {
|
|
108
|
+
if (event.key === "ArrowLeft") {
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
resizeThreadSidebarBy(-24);
|
|
111
|
+
} else if (event.key === "ArrowRight") {
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
resizeThreadSidebarBy(threadSidebarKeyboardStep);
|
|
114
|
+
} else if (event.key === "Home") {
|
|
115
|
+
event.preventDefault();
|
|
116
|
+
setSidebarWidth(threadSidebarMinWidth);
|
|
117
|
+
} else if (event.key === "End") {
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
setSidebarWidth(threadSidebarMaxWidth);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}) : null,
|
|
123
|
+
/* @__PURE__ */ jsx("div", {
|
|
124
|
+
id: sidebarId,
|
|
125
|
+
className: "think-thread-shell__sidebar",
|
|
126
|
+
"aria-hidden": isSidebarOpen ? void 0 : true,
|
|
127
|
+
inert: isSidebarOpen ? void 0 : true,
|
|
128
|
+
children: sidebar
|
|
129
|
+
}),
|
|
130
|
+
/* @__PURE__ */ jsx("div", {
|
|
131
|
+
className: "think-thread-shell__main",
|
|
132
|
+
children
|
|
133
|
+
}),
|
|
134
|
+
isSidebarOpen ? /* @__PURE__ */ jsx(Button, {
|
|
135
|
+
variant: "ghost",
|
|
136
|
+
color: "neutral",
|
|
137
|
+
className: "think-thread-shell__peek",
|
|
138
|
+
"aria-label": "Show selected thread",
|
|
139
|
+
onClick: () => setSidebarOpen(false)
|
|
140
|
+
}) : null
|
|
141
|
+
]
|
|
142
|
+
})
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
export { ThinkThreadShell };
|
|
@@ -2,6 +2,7 @@ import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
|
2
2
|
import { A as SearchIcon, h as FileIcon, k as RefreshIcon, n as ArrowLeftIcon } from "../icons-D2Q5n5C1.js";
|
|
3
3
|
import { Button } from "./Button.js";
|
|
4
4
|
import { a as CodeBlockCopyButton, i as CodeBlockContent, n as CodeBlockActions, o as CodeBlockFilename, p as CodeBlockTitle, r as CodeBlockContainer, s as CodeBlockHeader, t as CodeBlock } from "../CodeBlock-XNQOupQ3.js";
|
|
5
|
+
import { Input } from "./Input.js";
|
|
5
6
|
import { i as FileTreeFolder, r as FileTreeFile, t as FileTree } from "../FileTree-wMyZhhHO.js";
|
|
6
7
|
import * as React from "react";
|
|
7
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -277,11 +278,12 @@ function WorkspaceExplorer({ workspace, className, title = "Workspace", actions,
|
|
|
277
278
|
className: "workspace-explorer__body",
|
|
278
279
|
children: [showFilter ? /* @__PURE__ */ jsxs("label", {
|
|
279
280
|
className: "workspace-explorer__filter",
|
|
280
|
-
children: [/* @__PURE__ */ jsx(SearchIcon, { "aria-hidden": "true" }), /* @__PURE__ */ jsx(
|
|
281
|
+
children: [/* @__PURE__ */ jsx(SearchIcon, { "aria-hidden": "true" }), /* @__PURE__ */ jsx(Input, {
|
|
281
282
|
type: "search",
|
|
282
283
|
value: filter,
|
|
283
284
|
onChange: (event) => setFilter(event.currentTarget.value),
|
|
284
285
|
placeholder: filterPlaceholder,
|
|
286
|
+
className: "workspace-explorer__filter-input",
|
|
285
287
|
"aria-label": "Filter workspace files",
|
|
286
288
|
autoComplete: "off"
|
|
287
289
|
})]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/components/_internal/merge-refs.ts
|
|
2
|
+
function assignRef(ref, value) {
|
|
3
|
+
if (!ref) return;
|
|
4
|
+
if (typeof ref === "function") {
|
|
5
|
+
ref(value);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
ref.current = value;
|
|
9
|
+
}
|
|
10
|
+
function mergeRefs(...refs) {
|
|
11
|
+
const activeRefs = refs.filter(Boolean);
|
|
12
|
+
if (activeRefs.length === 0) return void 0;
|
|
13
|
+
return (value) => {
|
|
14
|
+
for (const activeRef of activeRefs) assignRef(activeRef, value);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { mergeRefs as n, assignRef as t };
|