@tangle-network/ui 6.0.0 → 8.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @tangle-network/ui
2
2
 
3
+ ## 8.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 831e935: One composer, no zombie API. `ChatInput` is deleted — the canonical composer is `AgentComposer` in `@tangle-network/sandbox-ui`, composed below the transcript by the app. `ChatContainer` is now transcript-only: the input props (`onSend`, `onCancel`, `placeholder`, `hideInput`, `modelLabel`, `onModelClick`, `pendingFiles`, `onRemoveFile`, `onAttach`, `disabled`) and the `PendingFile` type are removed. `ChatMessage` drops the no-op `avatar`/`hideAvatar` props. `ToolCallStep`/`ToolCallGroup` are no longer exported (internal adapters over `InlineToolItem`); the `ToolCallType`/`ToolCallStatus` types stay public via `ToolCallData`, and `ToolCallFeed` is unchanged.
8
+
9
+ ## 7.0.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 46592b3: Calmer chat/run design + named multi-theme system.
14
+
15
+ - `ChatMessage`/`RunGroup`: role labels move above the bubble (plain text-xs), avatar circles removed (`avatar`/`hideAvatar` are deprecated no-ops), `InlineToolItem` rows are taller with quiet inline failed/running text instead of uppercase pills. `ToolCallStep`/`ToolCallFeed` stories leave Storybook (source adapters remain).
16
+ - `@tangle-network/brand` adds `themes.css`: `[data-theme]` scopes (`aubergine`, `aubergine-light`, `arena`, `arena-light`, `tangle-light`) that re-skin every component through the `@theme` semantic mappings, plus a `Foundations/Theme Showcase` story.
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [46592b3]
21
+ - @tangle-network/brand@0.8.0
22
+
3
23
  ## 6.0.0
4
24
 
5
25
  ### Patch Changes
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Generic React UI components for Tangle products. Imports tokens from `@tangle-network/brand` (peer dep). Tailwind v4-native.
4
4
 
5
+ Component visual precedent is governed by the repo-level [brand guidelines](../../docs/brand-guidelines.md) and [component audit](../../docs/component-audit.md). Storybook examples are test surfaces; they are not automatically approved brand patterns.
6
+
5
7
  ## Install
6
8
 
7
9
  ```sh
package/dist/chat.d.ts CHANGED
@@ -7,83 +7,23 @@ import { AgentBranding } from './types.js';
7
7
  import { C as CustomToolRenderer } from './tool-display-z4JcDmMQ.js';
8
8
  import { R as Run, G as GroupedMessage } from './run-PfLmDAox.js';
9
9
  import { OpenUIAction } from './openui.js';
10
- import { T as ToolCallData } from './tool-call-feed-Bs3MyQMT.js';
10
+ import { T as ToolCallData } from './tool-call-feed-D9iofJgW.js';
11
11
 
12
12
  /**
13
- * ChatInput message input bar with file attach, drag-and-drop, send/cancel.
14
- *
15
- * - Auto-resizing textarea (up to max height)
16
- * - Enter to send, Shift+Enter for newline
17
- * - Drag-and-drop files onto the input with styled overlay
18
- * - File attachment button (files) + folder attachment button
19
- * - Pending file/folder chips
20
- * - Cancel button when streaming
21
- * - Optional model selector pill
13
+ * Transcript-only container: message list + auto-scroll. Composers are
14
+ * composed BELOW this by the app (the canonical one is `AgentComposer` in
15
+ * `@tangle-network/sandbox-ui`) this component never renders an input.
22
16
  */
23
- interface PendingFile {
24
- id: string;
25
- name: string;
26
- size: number;
27
- type: "file" | "folder";
28
- /** Number of files inside (for folders) */
29
- fileCount?: number;
30
- status: "pending" | "uploading" | "ready" | "error";
31
- }
32
- interface ChatInputProps {
33
- onSend: (message: string, files?: File[]) => void;
34
- onCancel?: () => void;
35
- isStreaming?: boolean;
36
- disabled?: boolean;
37
- placeholder?: string;
38
- /** Currently selected model label */
39
- modelLabel?: string;
40
- onModelClick?: () => void;
41
- /** Pending uploaded files */
42
- pendingFiles?: PendingFile[];
43
- onRemoveFile?: (id: string) => void;
44
- /** Called when files are attached (via button or drag-and-drop) */
45
- onAttach?: (files: FileList) => void;
46
- /** Called when a folder is selected via the folder button */
47
- onAttachFolder?: (files: FileList) => void;
48
- /** Accepted file types for the file input (e.g. ".pdf,.csv") */
49
- accept?: string;
50
- /** Drop zone overlay title */
51
- dropTitle?: string;
52
- /** Drop zone overlay description */
53
- dropDescription?: string;
54
- className?: string;
55
- /** Label above the input. Set to null to hide. Default: "Agent Command Deck" */
56
- inputLabel?: string | null;
57
- /** Status text shown when idle. Set to null to hide. Default: "Ready for next instruction" */
58
- idleStatus?: string | null;
59
- /** Status text shown when streaming. Set to null to hide. Default: "Streaming response" */
60
- streamingStatus?: string | null;
61
- /** Hide the Cmd+L focus shortcut hint */
62
- hideShortcutHint?: boolean;
63
- }
64
- declare function ChatInput({ onSend, onCancel, isStreaming, disabled, placeholder, modelLabel, onModelClick, pendingFiles, onRemoveFile, onAttach, onAttachFolder, accept, dropTitle, dropDescription, className, inputLabel, idleStatus, streamingStatus, hideShortcutHint, }: ChatInputProps): react_jsx_runtime.JSX.Element;
65
-
66
17
  interface ChatContainerProps {
67
18
  messages: SessionMessage[];
68
19
  partMap: Record<string, SessionPart[]>;
69
20
  isStreaming: boolean;
70
- onSend?: (text: string) => void;
71
- onCancel?: () => void;
72
21
  branding?: AgentBranding;
73
- placeholder?: string;
74
22
  className?: string;
75
- /** Hide the input area (useful for read-only views). */
76
- hideInput?: boolean;
77
23
  /** Custom renderer for tool details. Return ReactNode to override, null to use default. */
78
24
  renderToolDetail?: CustomToolRenderer;
79
25
  /** Presentation mode for the session view. */
80
26
  presentation?: "runs" | "timeline";
81
- modelLabel?: string;
82
- onModelClick?: () => void;
83
- pendingFiles?: PendingFile[];
84
- onRemoveFile?: (id: string) => void;
85
- onAttach?: (files: FileList) => void;
86
- disabled?: boolean;
87
27
  /** Callback when an OpenUI action button is pressed within inline OpenUI blocks. */
88
28
  onOpenUIAction?: (action: OpenUIAction) => void;
89
29
  /** Enable rendering OpenUI schemas inline in the chat timeline. Defaults to true. */
@@ -100,10 +40,10 @@ interface ChatContainerProps {
100
40
  }) => ReactNode;
101
41
  }
102
42
  /**
103
- * Full chat container: message list + auto-scroll + input area.
43
+ * Chat transcript container: message list + auto-scroll.
104
44
  * Orchestrates useRunGroups, useRunCollapseState, and useAutoScroll.
105
45
  */
106
- declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming, onSend, onCancel, branding, placeholder, className, hideInput, renderToolDetail, presentation, modelLabel, onModelClick, pendingFiles, onRemoveFile, onAttach, disabled, onOpenUIAction, enableOpenUI, renderRunActions, renderUserMessageActions, renderToolActions, }: ChatContainerProps) => react_jsx_runtime.JSX.Element>;
46
+ declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming, branding, className, renderToolDetail, presentation, onOpenUIAction, enableOpenUI, renderRunActions, renderUserMessageActions, renderToolActions, }: ChatContainerProps) => react_jsx_runtime.JSX.Element>;
107
47
 
108
48
  interface MessageListProps {
109
49
  groups: GroupedMessage[];
@@ -158,12 +98,8 @@ interface ChatMessageProps {
158
98
  assistantLabel?: string;
159
99
  /** Hide the role label row entirely */
160
100
  hideRoleLabel?: boolean;
161
- /** Hide the avatar icon */
162
- hideAvatar?: boolean;
163
- /** Custom avatar element (replaces default User/Bot icon) */
164
- avatar?: ReactNode;
165
101
  }
166
- declare function ChatMessage({ role, content, toolCalls, isStreaming, timestamp, className, userLabel, assistantLabel, hideRoleLabel, hideAvatar, avatar, }: ChatMessageProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatMessage({ role, content, toolCalls, isStreaming, timestamp, className, userLabel, assistantLabel, hideRoleLabel, }: ChatMessageProps): react_jsx_runtime.JSX.Element;
167
103
 
168
104
  interface ThinkingIndicatorProps {
169
105
  className?: string;
@@ -229,4 +165,4 @@ interface AgentTimelineProps {
229
165
  */
230
166
  declare function AgentTimeline({ items, isThinking, emptyState, className, }: AgentTimelineProps): react_jsx_runtime.JSX.Element | null;
231
167
 
232
- export { AgentTimeline, type AgentTimelineArtifactItem, type AgentTimelineCustomItem, type AgentTimelineItem, type AgentTimelineMessageItem, type AgentTimelineProps, type AgentTimelineStatusItem, type AgentTimelineTone, type AgentTimelineToolGroupItem, type AgentTimelineToolItem, ChatContainer, type ChatContainerProps, ChatInput, type ChatInputProps, ChatMessage, type ChatMessageProps, MessageList, type MessageListProps, type MessageRole, type PendingFile, ThinkingIndicator, type ThinkingIndicatorProps, UserMessage, type UserMessageProps };
168
+ export { AgentTimeline, type AgentTimelineArtifactItem, type AgentTimelineCustomItem, type AgentTimelineItem, type AgentTimelineMessageItem, type AgentTimelineProps, type AgentTimelineStatusItem, type AgentTimelineTone, type AgentTimelineToolGroupItem, type AgentTimelineToolItem, ChatContainer, type ChatContainerProps, ChatMessage, type ChatMessageProps, MessageList, type MessageListProps, type MessageRole, ThinkingIndicator, type ThinkingIndicatorProps, UserMessage, type UserMessageProps };
package/dist/chat.js CHANGED
@@ -1,15 +1,14 @@
1
1
  import {
2
2
  AgentTimeline,
3
3
  ChatContainer,
4
- ChatInput,
5
4
  ChatMessage,
6
5
  MessageList,
7
6
  ThinkingIndicator,
8
7
  UserMessage
9
- } from "./chunk-SJ6IL4HI.js";
8
+ } from "./chunk-UOLL2YHG.js";
10
9
  import "./chunk-AZWDI2JG.js";
11
- import "./chunk-LASW7CYH.js";
12
- import "./chunk-EOGJX2TU.js";
10
+ import "./chunk-QIRVZMQY.js";
11
+ import "./chunk-RKQDBRTC.js";
13
12
  import "./chunk-ULDNFLIM.js";
14
13
  import "./chunk-AAUNOHVL.js";
15
14
  import "./chunk-52Y3FMFI.js";
@@ -22,7 +21,6 @@ import "./chunk-RQHJBTEU.js";
22
21
  export {
23
22
  AgentTimeline,
24
23
  ChatContainer,
25
- ChatInput,
26
24
  ChatMessage,
27
25
  MessageList,
28
26
  ThinkingIndicator,
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-OEX7NZE3.js";
12
12
  import {
13
13
  parseToolEvent
14
- } from "./chunk-O6NUUCT2.js";
14
+ } from "./chunk-IWQZXL6A.js";
15
15
 
16
16
  // src/hooks/use-dropdown-menu.ts
17
17
  import { useEffect, useRef, useState } from "react";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ToolCallGroup,
3
3
  ToolCallStep
4
- } from "./chunk-EOGJX2TU.js";
4
+ } from "./chunk-RKQDBRTC.js";
5
5
  import {
6
6
  Markdown
7
7
  } from "./chunk-FJBTCTZM.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  InlineToolItem,
3
3
  LiveDuration
4
- } from "./chunk-EOGJX2TU.js";
4
+ } from "./chunk-RKQDBRTC.js";
5
5
  import {
6
6
  formatDuration,
7
7
  truncateText
@@ -142,18 +142,15 @@ function AssistantShell({
142
142
  isStreaming,
143
143
  children
144
144
  }) {
145
- return /* @__PURE__ */ jsxs2("div", { className: "flex gap-2.5", children: [
146
- /* @__PURE__ */ jsx2("div", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--brand-primary)] text-white", children: /* @__PURE__ */ jsx2(Bot, { className: "h-3.5 w-3.5" }) }),
147
- /* @__PURE__ */ jsxs2("div", { className: ASSISTANT_SHELL, children: [
148
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.14em] text-[var(--text-muted)]", children: [
149
- /* @__PURE__ */ jsx2("span", { children: branding.label }),
150
- isStreaming ? /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1.5 text-[var(--text-muted)]", children: [
151
- /* @__PURE__ */ jsx2(Loader2, { className: "h-3 w-3 animate-spin" }),
152
- "Thinking"
153
- ] }) : null
154
- ] }),
155
- children
156
- ] })
145
+ return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-1", children: [
146
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-1 font-medium text-muted-foreground text-xs", children: [
147
+ /* @__PURE__ */ jsx2("span", { children: branding.label }),
148
+ isStreaming ? /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1.5", children: [
149
+ /* @__PURE__ */ jsx2(Loader2, { className: "h-3 w-3 animate-spin" }),
150
+ "Thinking"
151
+ ] }) : null
152
+ ] }),
153
+ /* @__PURE__ */ jsx2("div", { className: ASSISTANT_SHELL, children })
157
154
  ] });
158
155
  }
159
156
  var CATEGORY_ICON_MAP = {
@@ -378,16 +375,7 @@ var RunGroup = memo2(
378
375
  "bg-transparent hover:bg-transparent"
379
376
  ),
380
377
  children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
381
- /* @__PURE__ */ jsx2(
382
- "div",
383
- {
384
- className: cn(
385
- "flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--brand-primary)] text-white"
386
- ),
387
- children: /* @__PURE__ */ jsx2(Bot, { className: "h-3.5 w-3.5" })
388
- }
389
- ),
390
- /* @__PURE__ */ jsx2("span", { className: cn("text-sm font-semibold", branding.textClass), children: branding.label }),
378
+ /* @__PURE__ */ jsx2("span", { className: cn("font-semibold text-sm", branding.textClass), children: branding.label }),
391
379
  renderSummary(run) ? /* @__PURE__ */ jsx2("span", { className: "text-[11px] text-muted-foreground", children: renderSummary(run) }) : null,
392
380
  collapsed && run.summaryText ? /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate text-[11px] text-foreground/70", children: run.summaryText }) : null,
393
381
  /* @__PURE__ */ jsxs2("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
@@ -233,7 +233,7 @@ var InlineToolItem = memo2(
233
233
  className
234
234
  ),
235
235
  children: [
236
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-2.5 py-1.5", children: [
236
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2.5 px-3 py-2.5", children: [
237
237
  /* @__PURE__ */ jsx3("div", { className: cn(
238
238
  "shrink-0",
239
239
  isRunning && "text-primary",
@@ -246,8 +246,8 @@ var InlineToolItem = memo2(
246
246
  /* @__PURE__ */ jsxs2("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
247
247
  isRunning && startTime ? /* @__PURE__ */ jsx3(LiveDuration, { startTime }) : null,
248
248
  !isRunning && durationMs != null ? /* @__PURE__ */ jsx3("span", { className: "text-[10px] font-mono tabular-nums text-muted-foreground", children: formatDuration(durationMs) }) : null,
249
- isError ? /* @__PURE__ */ jsx3("span", { className: "rounded-full border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] px-1.5 py-px text-[10px] font-semibold uppercase text-[var(--surface-danger-text)]", children: "Failed" }) : null,
250
- isRunning ? /* @__PURE__ */ jsx3("span", { className: "rounded-full border border-[var(--border-accent)] bg-primary/10 px-1.5 py-px text-[10px] font-semibold uppercase text-primary", children: "Running" }) : null,
249
+ isError ? /* @__PURE__ */ jsx3("span", { className: "text-[10px] font-medium text-[var(--surface-danger-text)]", children: "failed" }) : null,
250
+ isRunning ? /* @__PURE__ */ jsx3("span", { className: "text-[10px] font-medium text-primary", children: "running" }) : null,
251
251
  open ? /* @__PURE__ */ jsx3(ChevronDown, { className: "h-3 w-3 text-muted-foreground" }) : /* @__PURE__ */ jsx3(ChevronRight, { className: "h-3 w-3 text-muted-foreground" })
252
252
  ] })
253
253
  ] }),