@springbrand/message-panel 0.1.2 → 0.1.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/demo/camel-chat-showcase.tsx +1265 -0
  2. package/demo/fixtures.ts +292 -0
  3. package/demo/message-panel-chat-showcase.tsx +250 -0
  4. package/demo/message-panel-gallery.tsx +389 -0
  5. package/package.json +6 -16
  6. package/src/adapters/ai-sdk.ts +32 -0
  7. package/src/camel/camel-chat-messages.tsx +1435 -0
  8. package/src/camel/camel-model-select.tsx +88 -0
  9. package/src/camel/camel-plan-bar.tsx +115 -0
  10. package/src/camel/camel-prompt-input.tsx +547 -0
  11. package/src/camel/camel-tool-presentation.tsx +1270 -0
  12. package/src/camel/camel-turn.ts +334 -0
  13. package/src/camel/turn-summary-bar.tsx +81 -0
  14. package/src/chat-summary-panel.tsx +229 -0
  15. package/src/composer/chat-composer.tsx +216 -0
  16. package/src/composer/composer-attachments.tsx +138 -0
  17. package/src/composer/composer-trigger-popover.tsx +236 -0
  18. package/src/composer/composer.tsx +425 -0
  19. package/src/composer/drop-controller.ts +80 -0
  20. package/src/composer/types.ts +79 -0
  21. package/src/contracts.ts +138 -0
  22. package/src/conversation.tsx +76 -0
  23. package/src/internal/cn.ts +3 -0
  24. package/src/message-panel.tsx +368 -0
  25. package/src/message.tsx +254 -0
  26. package/src/parts/index.tsx +1149 -0
  27. package/src/parts/kind.ts +67 -0
  28. package/src/parts/plan.ts +64 -0
  29. package/src/parts/primitives.tsx +439 -0
  30. package/src/registry.ts +44 -0
  31. package/src/status.tsx +132 -0
  32. package/dist/demo/camel-chat-showcase.d.ts +0 -1
  33. package/dist/demo/camel-chat-showcase.js +0 -1007
  34. package/dist/demo/fixtures.d.ts +0 -32
  35. package/dist/demo/fixtures.js +0 -250
  36. package/dist/demo/index.js +0 -4
  37. package/dist/demo/message-panel-chat-showcase.d.ts +0 -1
  38. package/dist/demo/message-panel-chat-showcase.js +0 -114
  39. package/dist/demo/message-panel-gallery.d.ts +0 -1
  40. package/dist/demo/message-panel-gallery.js +0 -130
  41. package/dist/src/adapters/ai-sdk.d.ts +0 -4
  42. package/dist/src/adapters/ai-sdk.js +0 -25
  43. package/dist/src/camel/camel-chat-messages.d.ts +0 -44
  44. package/dist/src/camel/camel-chat-messages.js +0 -421
  45. package/dist/src/camel/camel-model-select.d.ts +0 -13
  46. package/dist/src/camel/camel-model-select.js +0 -7
  47. package/dist/src/camel/camel-plan-bar.d.ts +0 -5
  48. package/dist/src/camel/camel-plan-bar.js +0 -24
  49. package/dist/src/camel/camel-prompt-input.d.ts +0 -32
  50. package/dist/src/camel/camel-prompt-input.js +0 -182
  51. package/dist/src/camel/camel-tool-presentation.d.ts +0 -21
  52. package/dist/src/camel/camel-tool-presentation.js +0 -784
  53. package/dist/src/camel/camel-turn.d.ts +0 -57
  54. package/dist/src/camel/camel-turn.js +0 -203
  55. package/dist/src/camel/index.js +0 -7
  56. package/dist/src/camel/turn-summary-bar.d.ts +0 -8
  57. package/dist/src/camel/turn-summary-bar.js +0 -12
  58. package/dist/src/chat-summary-panel.d.ts +0 -22
  59. package/dist/src/chat-summary-panel.js +0 -26
  60. package/dist/src/composer/chat-composer.d.ts +0 -4
  61. package/dist/src/composer/chat-composer.js +0 -90
  62. package/dist/src/composer/composer-attachments.d.ts +0 -13
  63. package/dist/src/composer/composer-attachments.js +0 -47
  64. package/dist/src/composer/composer-trigger-popover.d.ts +0 -31
  65. package/dist/src/composer/composer-trigger-popover.js +0 -29
  66. package/dist/src/composer/composer.d.ts +0 -15
  67. package/dist/src/composer/composer.js +0 -180
  68. package/dist/src/composer/drop-controller.d.ts +0 -8
  69. package/dist/src/composer/drop-controller.js +0 -69
  70. package/dist/src/composer/index.js +0 -6
  71. package/dist/src/composer/types.d.ts +0 -62
  72. package/dist/src/composer/types.js +0 -1
  73. package/dist/src/contracts.d.ts +0 -94
  74. package/dist/src/contracts.js +0 -1
  75. package/dist/src/conversation.d.ts +0 -13
  76. package/dist/src/conversation.js +0 -18
  77. package/dist/src/index.js +0 -12
  78. package/dist/src/internal/cn.d.ts +0 -1
  79. package/dist/src/internal/cn.js +0 -3
  80. package/dist/src/message-panel.d.ts +0 -4
  81. package/dist/src/message-panel.js +0 -144
  82. package/dist/src/message.d.ts +0 -36
  83. package/dist/src/message.js +0 -83
  84. package/dist/src/parts/index.d.ts +0 -187
  85. package/dist/src/parts/index.js +0 -332
  86. package/dist/src/parts/kind.d.ts +0 -3
  87. package/dist/src/parts/kind.js +0 -69
  88. package/dist/src/parts/plan.d.ts +0 -10
  89. package/dist/src/parts/plan.js +0 -40
  90. package/dist/src/parts/primitives.d.ts +0 -70
  91. package/dist/src/parts/primitives.js +0 -153
  92. package/dist/src/registry.d.ts +0 -4
  93. package/dist/src/registry.js +0 -31
  94. package/dist/src/status.d.ts +0 -26
  95. package/dist/src/status.js +0 -74
  96. /package/{dist/demo/index.d.ts → demo/index.ts} +0 -0
  97. /package/{dist/src/camel/index.d.ts → src/camel/index.ts} +0 -0
  98. /package/{dist/src/composer/index.d.ts → src/composer/index.ts} +0 -0
  99. /package/{dist/src/index.d.ts → src/index.ts} +0 -0
package/src/status.tsx ADDED
@@ -0,0 +1,132 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { ThinkingOrb, type OrbState } from "thinking-orbs";
3
+ import type { MessagePanelStatus } from "./contracts";
4
+ import { cn } from "./internal/cn";
5
+ import { resolvePartKind, toolNameOfPart } from "./parts/kind";
6
+
7
+ export type PanelVisualState =
8
+ | "empty"
9
+ | "hydrating"
10
+ | "thinking"
11
+ | "streaming"
12
+ | "ready"
13
+ | "error"
14
+ | "recovering"
15
+ | "background";
16
+
17
+ export function derivePanelVisualState({
18
+ messageCount,
19
+ status,
20
+ isHydrating = false,
21
+ isRecovering = false,
22
+ isServerStreaming = false,
23
+ }: {
24
+ messageCount: number;
25
+ status: MessagePanelStatus;
26
+ isHydrating?: boolean;
27
+ isRecovering?: boolean;
28
+ isServerStreaming?: boolean;
29
+ }): PanelVisualState {
30
+ if (isHydrating) return "hydrating";
31
+ if (status === "error") return "error";
32
+ if (isRecovering) return "recovering";
33
+ if (isServerStreaming) return "background";
34
+ if (status === "submitted") return "thinking";
35
+ if (status === "streaming") return "streaming";
36
+ return messageCount === 0 ? "empty" : "ready";
37
+ }
38
+
39
+ export function ThinkingIndicator({
40
+ label = "Thinking…",
41
+ state = "solving",
42
+ className,
43
+ }: {
44
+ label?: string;
45
+ state?: OrbState;
46
+ className?: string;
47
+ }) {
48
+ return (
49
+ <div className={cn("sb-thinking", className)} role="status" aria-label={label}>
50
+ <ThinkingOrb state={state} size={20} aria-hidden="true" />
51
+ <span>{label}</span>
52
+ </div>
53
+ );
54
+ }
55
+
56
+ export function deriveThinkingActivity(part?: unknown): {
57
+ state: OrbState;
58
+ label: string;
59
+ } {
60
+ const kind = resolvePartKind(part);
61
+ const toolName = toolNameOfPart(part);
62
+ if (kind === "reasoning") return { state: "solving", label: "Reasoning…" };
63
+ if (kind === "text") return { state: "composing", label: "Composing answer…" };
64
+ if (
65
+ ["plan", "image", "chart", "dashboard"].includes(kind ?? "") ||
66
+ (toolName != null &&
67
+ /(?:^|[_-])(?:image|chart|artifact|render|write_file)(?:$|[_-])/i.test(
68
+ toolName,
69
+ ))
70
+ ) {
71
+ return { state: "shaping", label: "Shaping result…" };
72
+ }
73
+ if (
74
+ toolName != null &&
75
+ /(?:^|[_-])(?:search|fetch|browse|browser|web)(?:$|[_-])/i.test(toolName)
76
+ ) {
77
+ return { state: "searching", label: "Searching…" };
78
+ }
79
+ if (toolName != null) {
80
+ return {
81
+ state: "working",
82
+ label: `Running ${toolName.replaceAll("_", " ")}…`,
83
+ };
84
+ }
85
+ return part === undefined
86
+ ? { state: "solving", label: "Thinking…" }
87
+ : { state: "working", label: "Working…" };
88
+ }
89
+
90
+ type LoadingPhase = "idle" | "loading" | "done";
91
+
92
+ export function TopLoadingBar({ status }: { status: MessagePanelStatus }) {
93
+ const [phase, setPhase] = useState<LoadingPhase>("idle");
94
+ const previous = useRef(status);
95
+
96
+ useEffect(() => {
97
+ const before = previous.current;
98
+ previous.current = status;
99
+ if (status === "submitted") {
100
+ setPhase("loading");
101
+ return;
102
+ }
103
+ if (before === "submitted" && status === "streaming") {
104
+ setPhase("done");
105
+ const timeout = window.setTimeout(() => setPhase("idle"), 500);
106
+ return () => window.clearTimeout(timeout);
107
+ }
108
+ if (status !== "streaming") setPhase("idle");
109
+ }, [status]);
110
+
111
+ if (phase === "idle") return null;
112
+ return (
113
+ <div className="sb-top-loading" role="progressbar" aria-label="等待响应">
114
+ <span data-phase={phase} />
115
+ </div>
116
+ );
117
+ }
118
+
119
+ export function PanelStatus({
120
+ kind,
121
+ children,
122
+ }: {
123
+ kind: "hydrating" | "recovering" | "background" | "error";
124
+ children: React.ReactNode;
125
+ }) {
126
+ return (
127
+ <div className="sb-panel-status" data-kind={kind} role={kind === "error" ? "alert" : "status"}>
128
+ <span aria-hidden="true" />
129
+ {children}
130
+ </div>
131
+ );
132
+ }
@@ -1 +0,0 @@
1
- export declare function CamelChatShowcase(): import("react").JSX.Element;