@tangle-network/ui 11.51.16 → 11.51.18

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 (72) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/chat/thinking-indicator.js +9 -15
  3. package/dist/editor/tiptap-editor.js +4 -4
  4. package/dist/files/file-preview.js +1 -1
  5. package/dist/hooks/use-phone.d.ts +4 -0
  6. package/dist/hooks/use-phone.js +14 -0
  7. package/dist/hooks.d.ts +2 -1
  8. package/dist/hooks.js +2 -1
  9. package/dist/index.d.ts +2 -1
  10. package/dist/index.js +2 -1
  11. package/dist/openui/openui-artifact-renderer.js +7 -7
  12. package/dist/presentation.d.ts +1 -1
  13. package/dist/presentation.js +1 -1
  14. package/dist/primitives/artifact-pane.js +1 -1
  15. package/dist/primitives/heading.js +1 -1
  16. package/dist/primitives/progress.js +1 -1
  17. package/dist/primitives/sidebar-drop-zone.js +1 -1
  18. package/dist/primitives/stat-card.js +1 -1
  19. package/dist/primitives/toast.js +1 -1
  20. package/dist/primitives/upload-progress.js +2 -2
  21. package/dist/primitives/wizard.js +2 -2
  22. package/dist/run/expandable-content.js +1 -1
  23. package/dist/run/expanded-tool-detail.js +3 -3
  24. package/dist/run/run-group.js +11 -14
  25. package/dist/run/run-item-primitives.js +1 -1
  26. package/dist/tool-previews/command-preview.js +3 -3
  27. package/dist/tool-previews/diff-preview.js +2 -2
  28. package/dist/tool-previews/question-preview.js +1 -1
  29. package/dist/utils/time-ago.js +2 -1
  30. package/package.json +2 -2
  31. package/src/chat/thinking-indicator.tsx +2 -4
  32. package/src/editor/document-editor-pane.stories.tsx +1 -1
  33. package/src/editor/tiptap-editor.tsx +4 -4
  34. package/src/files/file-preview.tsx +1 -1
  35. package/src/hooks/index.ts +1 -0
  36. package/src/hooks/use-phone.ts +18 -0
  37. package/src/markdown/markdown.stories.tsx +1 -1
  38. package/src/openui/openui-artifact-renderer.tsx +7 -7
  39. package/src/presentation.ts +1 -1
  40. package/src/primitives/artifact-pane.tsx +1 -1
  41. package/src/primitives/avatar.stories.tsx +3 -3
  42. package/src/primitives/badge.stories.tsx +3 -3
  43. package/src/primitives/card.stories.tsx +1 -1
  44. package/src/primitives/compliance-badge.stories.tsx +3 -3
  45. package/src/primitives/dropdown-menu.stories.tsx +1 -1
  46. package/src/primitives/heading.tsx +1 -1
  47. package/src/primitives/input.stories.tsx +2 -2
  48. package/src/primitives/label.stories.tsx +3 -3
  49. package/src/primitives/progress.stories.tsx +5 -5
  50. package/src/primitives/progress.tsx +1 -1
  51. package/src/primitives/select.stories.tsx +3 -3
  52. package/src/primitives/sidebar-drop-zone.stories.tsx +1 -1
  53. package/src/primitives/sidebar-drop-zone.tsx +1 -1
  54. package/src/primitives/skeleton.stories.tsx +4 -4
  55. package/src/primitives/stat-card.stories.tsx +22 -33
  56. package/src/primitives/stat-card.tsx +1 -1
  57. package/src/primitives/switch.stories.tsx +2 -2
  58. package/src/primitives/tabs.stories.tsx +3 -3
  59. package/src/primitives/toast.tsx +1 -1
  60. package/src/primitives/upload-progress.tsx +2 -2
  61. package/src/primitives/wizard.tsx +1 -1
  62. package/src/run/expandable-content.tsx +1 -1
  63. package/src/run/expanded-tool-detail.tsx +3 -3
  64. package/src/run/inline-thinking-item.stories.tsx +3 -3
  65. package/src/run/inline-tool-item.stories.tsx +3 -3
  66. package/src/run/run-group.tsx +9 -9
  67. package/src/run/run-item-primitives.tsx +1 -1
  68. package/src/styles/presentation.css +1 -1
  69. package/src/tool-previews/command-preview.tsx +3 -3
  70. package/src/tool-previews/diff-preview.tsx +2 -2
  71. package/src/tool-previews/question-preview.tsx +1 -1
  72. package/src/utils/time-ago.ts +1 -1
@@ -104,7 +104,7 @@ export const Overview: Story = {
104
104
  render: () => (
105
105
  <div className="flex flex-col gap-10 p-6 w-[480px]">
106
106
  <div>
107
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mb-4">Default (segmented)</div>
107
+ <div className="text-muted-foreground text-xs font-mono mb-4">Default (segmented)</div>
108
108
  <Tabs defaultValue="overview">
109
109
  <TabsList>
110
110
  <TabsTrigger value="overview">Overview</TabsTrigger>
@@ -137,7 +137,7 @@ export const Overview: Story = {
137
137
  </div>
138
138
 
139
139
  <div>
140
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mb-4">Pills</div>
140
+ <div className="text-muted-foreground text-xs font-mono mb-4">Pills</div>
141
141
  <Tabs defaultValue="all">
142
142
  <TabsList variant="pills">
143
143
  <TabsTrigger value="all" variant="pills">All</TabsTrigger>
@@ -157,7 +157,7 @@ export const Overview: Story = {
157
157
  </div>
158
158
 
159
159
  <div>
160
- <div className="text-muted-foreground text-xs font-mono uppercase tracking-widest mb-4">Underline</div>
160
+ <div className="text-muted-foreground text-xs font-mono mb-4">Underline</div>
161
161
  <Tabs defaultValue="settings">
162
162
  <TabsList variant="underline">
163
163
  <TabsTrigger value="settings" variant="underline">Settings</TabsTrigger>
@@ -13,7 +13,7 @@ import { focusRing } from "../lib/focus";
13
13
  import { cn } from "../lib/utils";
14
14
 
15
15
  const toastVariants = cva(
16
- "pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-lg border p-4 shadow-lg transition-all",
16
+ "pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-lg border p-4 shadow-lg transition-[transform,opacity]",
17
17
  {
18
18
  variants: {
19
19
  variant: {
@@ -67,8 +67,8 @@ export function UploadProgress({ files, onRemove, onRetry, className }: UploadPr
67
67
  {file.status === "uploading" && file.progress !== undefined && (
68
68
  <div className="mt-1 h-1 w-full overflow-hidden rounded-full bg-muted/50">
69
69
  <div
70
- className="h-full rounded-full bg-primary transition-all"
71
- style={{ width: `${file.progress}%` }}
70
+ className="h-full w-full rounded-full bg-primary transition-transform duration-300 ease-out"
71
+ style={{ transform: `translateX(-${100 - file.progress}%)` }}
72
72
  />
73
73
  </div>
74
74
  )}
@@ -137,7 +137,7 @@ export function Wizard({ children, step, defaultStep = 0, onStepChange, onFinish
137
137
  </p>
138
138
  <div className="mt-2 h-1 overflow-hidden rounded-full bg-muted" role="progressbar"
139
139
  aria-valuemin={1} aria-valuemax={total} aria-valuenow={current + 1} aria-label={`Step ${current + 1} of ${total}`}>
140
- <div className="h-full rounded-full bg-primary transition-all" style={{ width: `${((current + 1) / total) * 100}%` }} />
140
+ <div className="h-full w-full rounded-full bg-primary transition-transform duration-300 ease-out" style={{ transform: `translateX(-${100 - ((current + 1) / total) * 100}%)` }} />
141
141
  </div>
142
142
  </div>
143
143
  {steps.map((child, index) => index === current
@@ -68,7 +68,7 @@ export function ExpandableContent({
68
68
  type="button"
69
69
  onClick={() => setExpanded((value) => !value)}
70
70
  className={cn(
71
- "mt-1 text-[11px] font-medium text-muted-foreground transition-colors hover:text-foreground",
71
+ "mt-1 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
72
72
  toggleClassName,
73
73
  )}
74
74
  >
@@ -128,7 +128,7 @@ export const ExpandedToolDetail = memo(({ part }: ExpandedToolDetailProps) => {
128
128
  <div className="overflow-hidden rounded-[var(--radius-lg)] border border-border bg-card">
129
129
  <div className="flex items-center gap-2 border-b border-border bg-background px-3 py-2">
130
130
  <ArrowRight className="h-3 w-3 text-primary" />
131
- <span className="text-xs font-medium uppercase tracking-[0.08em] text-muted-foreground">
131
+ <span className="text-xs font-medium text-muted-foreground">
132
132
  Input
133
133
  </span>
134
134
  </div>
@@ -141,7 +141,7 @@ export const ExpandedToolDetail = memo(({ part }: ExpandedToolDetailProps) => {
141
141
  <div className="overflow-hidden rounded-[var(--radius-lg)] border border-border bg-card">
142
142
  <div className="flex items-center gap-2 border-b border-border bg-background px-3 py-2">
143
143
  <ArrowLeft className="h-3 w-3 text-primary" />
144
- <span className="text-xs font-medium uppercase tracking-[0.08em] text-muted-foreground">
144
+ <span className="text-xs font-medium text-muted-foreground">
145
145
  Output
146
146
  </span>
147
147
  </div>
@@ -164,7 +164,7 @@ export const ExpandedToolDetail = memo(({ part }: ExpandedToolDetailProps) => {
164
164
  <div className="overflow-hidden rounded-[var(--radius-lg)] border border-[var(--surface-danger-border)]">
165
165
  <div className="flex items-center gap-2 border-b border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] px-3 py-2">
166
166
  <RunStatusIcon status="failed" aria-hidden className="size-3" />
167
- <span className="text-xs font-medium uppercase tracking-[0.08em] text-[var(--surface-danger-text)]">
167
+ <span className="text-xs font-medium text-[var(--surface-danger-text)]">
168
168
  Error
169
169
  </span>
170
170
  </div>
@@ -154,11 +154,11 @@ export const UnifiedWithToolRow: Story = {
154
154
  export const AllStates: Story = {
155
155
  render: () => (
156
156
  <div className="p-6 max-w-2xl space-y-3">
157
- <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground px-1">Active</p>
157
+ <p className="text-xs font-mono text-muted-foreground px-1">Active</p>
158
158
  <InlineThinkingItem part={thinkingActive} defaultOpen={true} autoCollapse={false} />
159
- <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground px-1 pt-2">Complete (collapsed)</p>
159
+ <p className="text-xs font-mono text-muted-foreground px-1 pt-2">Complete (collapsed)</p>
160
160
  <InlineThinkingItem part={thinkingComplete} defaultOpen={false} autoCollapse={false} />
161
- <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground px-1 pt-2">Complete (expanded)</p>
161
+ <p className="text-xs font-mono text-muted-foreground px-1 pt-2">Complete (expanded)</p>
162
162
  <InlineThinkingItem part={thinkingLong} defaultOpen={true} autoCollapse={false} />
163
163
  </div>
164
164
  ),
@@ -211,11 +211,11 @@ export const GroupedSequence: Story = {
211
211
  export const AllStates: Story = {
212
212
  render: () => (
213
213
  <div className="p-6 max-w-2xl space-y-3">
214
- <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground px-1">Completed</p>
214
+ <p className="text-xs font-mono text-muted-foreground px-1">Completed</p>
215
215
  <InlineToolItem part={bashComplete} groupPosition="single" />
216
- <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground px-1 pt-2">Running</p>
216
+ <p className="text-xs font-mono text-muted-foreground px-1 pt-2">Running</p>
217
217
  <InlineToolItem part={bashRunning} groupPosition="single" />
218
- <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground px-1 pt-2">Error</p>
218
+ <p className="text-xs font-mono text-muted-foreground px-1 pt-2">Error</p>
219
219
  <InlineToolItem part={bashError} groupPosition="single" />
220
220
  </div>
221
221
  ),
@@ -80,7 +80,7 @@ const DEFAULT_BRANDING: AgentBranding = {
80
80
  };
81
81
 
82
82
  const ASSISTANT_SHELL =
83
- "min-w-0 flex-1 space-y-3 rounded-[26px] border border-[var(--border-subtle)] bg-[color:color-mix(in_srgb,var(--bg-card)_94%,transparent)] px-5 py-4 shadow-[0_1px_2px_rgba(15,23,42,0.04)]";
83
+ "min-w-0 flex-1 space-y-3 rounded-[var(--radius-panel)] border border-[var(--border-subtle)] bg-[color:color-mix(in_srgb,var(--bg-card)_94%,transparent)] px-5 py-4 shadow-[0_1px_2px_rgba(15,23,42,0.04)]";
84
84
 
85
85
  function AssistantShell({
86
86
  branding,
@@ -251,7 +251,7 @@ function CategoryBadges({ categories }: { categories: Set<ToolCategory> }) {
251
251
  <span
252
252
  key={cat}
253
253
  title={cat}
254
- className="flex h-5 w-5 items-center justify-center rounded border border-border text-muted-foreground"
254
+ className="flex h-5 w-5 items-center justify-center text-muted-foreground"
255
255
  >
256
256
  <Icon className="h-3 w-3" />
257
257
  </span>
@@ -326,10 +326,10 @@ export const RunGroup = memo(
326
326
  const pendingResponse = (
327
327
  <AssistantShell branding={branding} isStreaming={true}>
328
328
  <div className="flex items-center gap-2 px-0.5 py-0.5 text-sm text-[var(--text-muted)]">
329
- <span className="flex gap-[5px]">
330
- <span className="h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "0ms" }} />
331
- <span className="h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "150ms" }} />
332
- <span className="h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "300ms" }} />
329
+ <span className="flex gap-1">
330
+ <span className="h-2 w-2 animate-[tangle-breathe_var(--motion-ambient)_infinite] motion-reduce:animate-none rounded-full bg-[var(--brand-glow)]" />
331
+ <span className="h-2 w-2 animate-[tangle-breathe_var(--motion-ambient)_infinite] motion-reduce:animate-none rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "200ms" }} />
332
+ <span className="h-2 w-2 animate-[tangle-breathe_var(--motion-ambient)_infinite] motion-reduce:animate-none rounded-full bg-[var(--brand-glow)]" style={{ animationDelay: "400ms" }} />
333
333
  </span>
334
334
  </div>
335
335
  </AssistantShell>
@@ -474,16 +474,16 @@ export const RunGroup = memo(
474
474
  {branding.label}
475
475
  </span>
476
476
  {renderSummary(run) ? (
477
- <span className="text-[11px] text-muted-foreground">{renderSummary(run)}</span>
477
+ <span className="text-xs text-muted-foreground">{renderSummary(run)}</span>
478
478
  ) : null}
479
479
  {collapsed && run.summaryText ? (
480
- <span className="min-w-0 truncate text-[11px] text-foreground/70">
480
+ <span className="min-w-0 truncate text-xs text-foreground/70">
481
481
  {run.summaryText}
482
482
  </span>
483
483
  ) : null}
484
484
  <span className="ml-auto flex shrink-0 items-center gap-1.5">
485
485
  <CategoryBadges categories={stats.toolCategories} />
486
- <span className="inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground">
486
+ <span className="inline-flex items-center gap-1 text-xs text-muted-foreground">
487
487
  <RunStatusIcon status={isStreaming ? "running" : "done"} aria-hidden className="size-3" />
488
488
  {statusMeta(isStreaming ? "running" : "done").label}
489
489
  </span>
@@ -5,7 +5,7 @@ export function LiveDuration({ startTime }: { startTime: number }) {
5
5
  const elapsed = useLiveTime(100) - startTime;
6
6
 
7
7
  return (
8
- <span className="text-xs font-mono text-neutral-400 dark:text-neutral-500 tabular-nums">
8
+ <span className="text-xs font-mono text-muted-foreground tabular-nums">
9
9
  {formatDuration(elapsed)}
10
10
  </span>
11
11
  );
@@ -5,7 +5,7 @@
5
5
  .tangle-heading[data-variant="page"] { font-size: var(--font-size-3xl); }
6
6
  .tangle-heading[data-variant="section"] { font-size: var(--font-size-xl); }
7
7
  .tangle-heading[data-variant="subsection"] { font-size: var(--font-size-base); }
8
- .tangle-heading[data-variant="eyebrow"] { font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: hsl(var(--muted-foreground)); }
8
+ .tangle-heading[data-variant="eyebrow"] { font-size: var(--font-size-xs); line-height: 1rem; font-weight: 500; letter-spacing: 0; color: hsl(var(--muted-foreground)); }
9
9
  .tangle-page-header { min-width: 0; margin-bottom: 1.5rem; }
10
10
  .tangle-page-header-main { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1.5rem; }
11
11
  .tangle-intro .tangle-page-header-main { display: block; }
@@ -139,7 +139,7 @@ function ExitBadge({
139
139
  }) {
140
140
  if (status === "running" || status === "pending") {
141
141
  return (
142
- <span className="inline-flex shrink-0 items-center gap-1 text-[11px] text-muted-foreground">
142
+ <span className="inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground">
143
143
  <Loader2 className="h-3 w-3 animate-spin" aria-hidden="true" />
144
144
  running
145
145
  </span>
@@ -171,7 +171,7 @@ function ExitBadge({
171
171
  <span
172
172
  className={cn(
173
173
  // Every badge has a border, so mixed rows keep one height.
174
- "inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-[11px] font-medium tabular-nums",
174
+ "inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-xs font-medium tabular-nums",
175
175
  tone === "danger" &&
176
176
  "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
177
177
  tone === "success" &&
@@ -253,7 +253,7 @@ function OutputRegion({
253
253
  type="button"
254
254
  onClick={() => setFull(true)}
255
255
  className={cn(
256
- "w-full border-t border-white/10 px-3 py-1.5 text-left font-sans text-[11px] font-medium text-muted-foreground transition-colors hover:text-foreground",
256
+ "w-full border-t border-white/10 px-3 py-1.5 text-left font-sans text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
257
257
  focusRing,
258
258
  )}
259
259
  >
@@ -64,7 +64,7 @@ export const DiffPreview = memo(({ part }: DiffPreviewProps) => {
64
64
  ) : null}
65
65
  {!payload.diff && payload.before ? (
66
66
  <div className="space-y-2">
67
- <div className="text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground">
67
+ <div className="text-xs font-medium text-muted-foreground">
68
68
  Before
69
69
  </div>
70
70
  <CodeBlock code={payload.before} language="text" className="rounded-[var(--radius-md)]" />
@@ -72,7 +72,7 @@ export const DiffPreview = memo(({ part }: DiffPreviewProps) => {
72
72
  ) : null}
73
73
  {!payload.diff && payload.after ? (
74
74
  <div className="space-y-2">
75
- <div className="text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground">
75
+ <div className="text-xs font-medium text-muted-foreground">
76
76
  After
77
77
  </div>
78
78
  <CodeBlock code={payload.after} language="text" className="rounded-[var(--radius-md)]" />
@@ -83,7 +83,7 @@ export const QuestionPreview = memo(({ part }: QuestionPreviewProps) => {
83
83
  key={`${question}-${index}`}
84
84
  className="rounded-[var(--radius-md)] border border-border bg-muted px-3 py-3"
85
85
  >
86
- <div className="text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground">
86
+ <div className="text-xs font-medium text-muted-foreground">
87
87
  Question {index + 1}
88
88
  </div>
89
89
  <div className="mt-2 text-sm leading-relaxed text-foreground">
@@ -5,5 +5,5 @@ export function timeAgo(ts: number): string {
5
5
  const mins = Math.floor(secs / 60);
6
6
  if (mins < 60) return `${mins}m ago`;
7
7
  const hrs = Math.floor(mins / 60);
8
- return `${hrs}h ago`;
8
+ return hrs < 24 ? `${hrs}h ago` : `${Math.floor(hrs / 24)}d ago`;
9
9
  }