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

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 (36) hide show
  1. package/cloud-os/README.md +71 -0
  2. package/cloud-os/capability-chip.tsx +35 -0
  3. package/cloud-os/chat/activity-indicator.tsx +29 -0
  4. package/cloud-os/chat/cloud-os-chat-messages.tsx +660 -0
  5. package/cloud-os/chat/markdown-message.tsx +78 -0
  6. package/cloud-os/chat/rich-blocks.tsx +787 -0
  7. package/cloud-os/chat/tool-presentation.ts +586 -0
  8. package/cloud-os/chat/tool-rows.tsx +216 -0
  9. package/cloud-os/chat/transcript-model.ts +780 -0
  10. package/cloud-os/composer/cloud-os-chat-input.tsx +686 -0
  11. package/cloud-os/file-view.tsx +258 -0
  12. package/cloud-os/index.ts +123 -0
  13. package/cloud-os/internal/cn.ts +6 -0
  14. package/cloud-os/internal/theme-context.tsx +16 -0
  15. package/cloud-os/layout/cloud-os-root.tsx +34 -0
  16. package/cloud-os/layout/cloud-os-workspace-split.tsx +228 -0
  17. package/cloud-os/primitives/dropdown-menu.tsx +82 -0
  18. package/cloud-os/primitives/tooltip.tsx +68 -0
  19. package/cloud-os/primitives/workshop-controls.tsx +114 -0
  20. package/cloud-os/styles/cloud-os.css +553 -0
  21. package/cloud-os/workspace/cloud-os-workspace-panel.tsx +272 -0
  22. package/demo/camel-chat-showcase.tsx +13 -917
  23. package/demo/chat-scenarios.ts +926 -0
  24. package/demo/cloud-os-chat-showcase.tsx +481 -0
  25. package/demo/index.ts +2 -0
  26. package/package.json +17 -5
  27. package/src/camel/camel-chat-messages.tsx +41 -18
  28. package/src/camel/camel-prompt-input.tsx +2 -1
  29. package/src/chat-summary-panel.tsx +1 -1
  30. package/src/composer/chat-composer.tsx +2 -1
  31. package/src/composer/composer-trigger-popover.tsx +1 -1
  32. package/src/composer/composer.tsx +2 -1
  33. package/src/composer/index.ts +1 -0
  34. package/src/composer/key-rules.ts +12 -0
  35. package/src/message.tsx +0 -8
  36. package/src/styles/index.css +4 -1
@@ -39,6 +39,7 @@ import {
39
39
  type ReactNode,
40
40
  } from "react";
41
41
  import { ComposerTriggerPopover } from "../composer/composer-trigger-popover";
42
+ import { isComposingKeyEvent } from "../composer/key-rules";
42
43
  import type { ComposerCommand } from "../composer/types";
43
44
  import { cn } from "../internal/cn";
44
45
 
@@ -345,7 +346,7 @@ function CamelPromptInputContent({
345
346
  if (
346
347
  event.key === "Enter" &&
347
348
  !event.shiftKey &&
348
- !event.nativeEvent.isComposing
349
+ !isComposingKeyEvent(event.nativeEvent)
349
350
  ) {
350
351
  event.preventDefault();
351
352
  submit();
@@ -103,7 +103,7 @@ export function ChatSummaryPanel({
103
103
  return (
104
104
  <aside
105
105
  className={cn(
106
- "w-[19rem] min-w-0 max-w-full overflow-hidden rounded-2xl border border-border bg-popover shadow-card",
106
+ "absolute right-3 top-11 z-30 w-[19rem] min-w-0 max-w-[calc(100%-1.5rem)] overflow-hidden rounded-2xl border border-border bg-popover shadow-card",
107
107
  "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200 motion-reduce:animate-none",
108
108
  className,
109
109
  )}
@@ -10,6 +10,7 @@ import {
10
10
  type KeyboardEvent,
11
11
  } from "react";
12
12
  import { cn } from "../internal/cn";
13
+ import { isComposingKeyEvent } from "./key-rules";
13
14
  import { Composer } from "./composer";
14
15
  import type {
15
16
  ChatComposerProps,
@@ -152,7 +153,7 @@ function ChatComposerInner<TAttachment>(
152
153
  if (
153
154
  (event.key === "Enter" &&
154
155
  !event.shiftKey &&
155
- !event.nativeEvent.isComposing) ||
156
+ !isComposingKeyEvent(event.nativeEvent)) ||
156
157
  event.key === "Tab"
157
158
  ) {
158
159
  const command = filtered[active] ?? filtered[0];
@@ -156,7 +156,7 @@ function Items({
156
156
  {item.label}
157
157
  </span>
158
158
  {item.description && (
159
- <span className="ms-5.5 text-xs leading-tight text-muted-foreground">
159
+ <span className="ms-5.5 w-full truncate text-xs leading-tight text-muted-foreground">
160
160
  {item.description}
161
161
  </span>
162
162
  )}
@@ -26,6 +26,7 @@ import {
26
26
  Attachments,
27
27
  } from "./composer-attachments";
28
28
  import { useComposerDrop } from "./drop-controller";
29
+ import { isComposingKeyEvent } from "./key-rules";
29
30
  import type {
30
31
  ComposerAttachmentView,
31
32
  ComposerProps,
@@ -247,7 +248,7 @@ function ComposerInner<TAttachment>(
247
248
  if (
248
249
  event.key === "Enter" &&
249
250
  !event.shiftKey &&
250
- !event.nativeEvent.isComposing
251
+ !isComposingKeyEvent(event.nativeEvent)
251
252
  ) {
252
253
  event.preventDefault();
253
254
  if (canSend) void submit();
@@ -3,4 +3,5 @@ export * from "./composer-attachments";
3
3
  export * from "./composer-trigger-popover";
4
4
  export * from "./chat-composer";
5
5
  export * from "./drop-controller";
6
+ export * from "./key-rules";
6
7
  export * from "./types";
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Whether Enter belongs to an input method rather than to the Composer.
3
+ *
4
+ * Both signals are honoured on their own: some Chinese input methods report only the
5
+ * legacy `keyCode === 229`, and either one alone means a word is still being composed.
6
+ */
7
+ export function isComposingKeyEvent(event: {
8
+ isComposing?: boolean;
9
+ keyCode?: number;
10
+ }): boolean {
11
+ return event.isComposing === true || event.keyCode === 229;
12
+ }
package/src/message.tsx CHANGED
@@ -85,13 +85,6 @@ export const MessageAction = forwardRef<HTMLButtonElement, MessageActionProps>(
85
85
  MessageAction.displayName = "MessageAction";
86
86
 
87
87
  const streamdownPlugins = { cjk, code, math, mermaid };
88
- const streamAnimation = {
89
- animation: "fadeIn",
90
- sep: "word",
91
- duration: 260,
92
- stagger: 14,
93
- } as const;
94
-
95
88
  export type MessageResponseProps = StreamdownProps & {
96
89
  streaming?: boolean;
97
90
  resolveUrl?: MessageUrlResolver;
@@ -146,7 +139,6 @@ export const MessageResponse = memo(
146
139
  ? {
147
140
  mode: "streaming" as const,
148
141
  isAnimating: true,
149
- animated: streamAnimation,
150
142
  }
151
143
  : { mode: "static" as const })}
152
144
  {...props}
@@ -2128,7 +2128,10 @@
2128
2128
  min-height: 120px;
2129
2129
  gap: 0;
2130
2130
  border-radius: 16px;
2131
- background: #1c1c1a;
2131
+ /* 这里曾写死 #1c1c1a,于是 light 档下输入框还是近黑的。
2132
+ 表面色一律走 token:--mp-card → --card(light #fff / dark #1c1c1c)。
2133
+ 本节其余几个写死色是状态/图标强调色(琥珀、蓝),两档背景上都读得出来,不在此列。 */
2134
+ background: var(--mp-card);
2132
2135
  box-shadow: none;
2133
2136
  }
2134
2137