@vvedantb/ui 0.17.0 → 0.18.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.
Files changed (130) hide show
  1. package/README.md +253 -3
  2. package/package.json +13 -5
  3. package/shell/src/SidebarResize.tsx +1 -4
  4. package/src/ai-elements/__snapshots__/queue.test.tsx.snap +11 -0
  5. package/src/ai-elements/activity-question-utils.ts +26 -0
  6. package/src/ai-elements/activity-question.tsx +159 -0
  7. package/src/ai-elements/activity-shared.tsx +459 -0
  8. package/src/ai-elements/activity-step-detail.tsx +115 -0
  9. package/src/ai-elements/activity-step-label.ts +981 -0
  10. package/src/ai-elements/activity-tasks-utils.ts +199 -0
  11. package/src/ai-elements/activity-tasks.tsx +770 -0
  12. package/src/ai-elements/artifact.tsx +162 -52
  13. package/src/ai-elements/attachments.tsx +62 -32
  14. package/src/ai-elements/code-block.tsx +76 -22
  15. package/src/ai-elements/context.tsx +370 -0
  16. package/src/ai-elements/conversation.tsx +186 -62
  17. package/src/ai-elements/file-chip.tsx +53 -0
  18. package/src/ai-elements/message.tsx +161 -50
  19. package/src/ai-elements/model-picker-content.tsx +505 -0
  20. package/src/ai-elements/model-picker-types.ts +56 -0
  21. package/src/ai-elements/model-picker.tsx +301 -0
  22. package/src/ai-elements/model-selector.tsx +102 -21
  23. package/src/ai-elements/plan.tsx +130 -0
  24. package/src/ai-elements/prompt-input-settings.tsx +144 -0
  25. package/src/ai-elements/prompt-input-speech.tsx +189 -0
  26. package/src/ai-elements/prompt-input-traits.tsx +281 -0
  27. package/src/ai-elements/prompt-input.tsx +320 -134
  28. package/src/ai-elements/provider-icon.tsx +133 -0
  29. package/src/ai-elements/queue.tsx +293 -9
  30. package/src/ai-elements/shimmer.tsx +72 -1
  31. package/src/ai-elements/simple-model-ladder.tsx +108 -0
  32. package/src/ai-elements/test-results.tsx +510 -0
  33. package/src/ai-elements/trace.tsx +243 -0
  34. package/src/ai-elements/use-streaming-disclosure.ts +50 -0
  35. package/src/ai-elements/web-preview.tsx +349 -0
  36. package/src/composer/input-area/ComposerSlashMenu.tsx +1 -1
  37. package/src/index.ts +66 -12
  38. package/src/kibo/avatar-stack.tsx +40 -0
  39. package/src/kibo/contribution-graph.tsx +539 -0
  40. package/src/kibo/cursor.tsx +72 -0
  41. package/src/kibo/gantt-features.tsx +439 -0
  42. package/src/kibo/gantt-header.tsx +181 -0
  43. package/src/kibo/gantt-provider.tsx +657 -0
  44. package/src/kibo/gantt-sidebar.tsx +157 -0
  45. package/src/kibo/gantt-timeline.tsx +154 -0
  46. package/src/kibo/index.ts +151 -0
  47. package/src/kibo/kanban.tsx +338 -0
  48. package/src/kibo/kanbanDropTarget.ts +25 -0
  49. package/src/kibo/list.tsx +162 -0
  50. package/src/kibo/theme-switcher.tsx +109 -0
  51. package/src/kibo/video-player.tsx +237 -0
  52. package/src/markdown/Markdown.tsx +112 -0
  53. package/src/markdown/MarkdownBlockquote.tsx +45 -0
  54. package/src/markdown/MarkdownCodeBlock.tsx +197 -0
  55. package/src/markdown/MarkdownInlineCode.tsx +40 -0
  56. package/src/markdown/MarkdownLink.tsx +92 -0
  57. package/src/markdown/codeFence.ts +57 -0
  58. package/src/markdown/codeHighlight.ts +138 -0
  59. package/src/markdown/incrementalBlocks.ts +182 -0
  60. package/src/markdown/index.ts +3 -0
  61. package/src/markdown/markdownClipboard.ts +178 -0
  62. package/src/markdown/mermaid.ts +155 -0
  63. package/src/markdown/rehypeGithubAlerts.ts +80 -0
  64. package/src/motion/presets.ts +24 -0
  65. package/src/ui/__snapshots__/alt-wrappers.test.tsx.snap +19 -0
  66. package/src/ui/__snapshots__/sonner-dom.test.tsx.snap +5 -0
  67. package/src/ui/_menu-parts.tsx +29 -0
  68. package/src/ui/accordion.alt.tsx +46 -53
  69. package/src/ui/accordion.tsx +59 -10
  70. package/src/ui/avatar.tsx +56 -0
  71. package/src/ui/badge.tsx +45 -21
  72. package/src/ui/border-beam.tsx +97 -0
  73. package/src/ui/button-group.tsx +50 -21
  74. package/src/ui/button.tsx +67 -45
  75. package/src/ui/calendar.tsx +48 -5
  76. package/src/ui/card.tsx +77 -8
  77. package/src/ui/carousel.tsx +60 -0
  78. package/src/ui/centered-spinner.tsx +30 -0
  79. package/src/ui/checkbox.tsx +34 -16
  80. package/src/ui/clear-input.alt.tsx +33 -75
  81. package/src/ui/clear-input.tsx +140 -15
  82. package/src/ui/collapsible.tsx +40 -2
  83. package/src/ui/command.tsx +143 -70
  84. package/src/ui/context-menu.tsx +159 -93
  85. package/src/ui/crossfade-icon.tsx +123 -0
  86. package/src/ui/dialog.tsx +154 -70
  87. package/src/ui/dropdown-menu.tsx +177 -117
  88. package/src/ui/hover-card.tsx +59 -17
  89. package/src/ui/input-group.alt.tsx +83 -83
  90. package/src/ui/input-group.tsx +129 -58
  91. package/src/ui/input.tsx +13 -4
  92. package/src/ui/label.tsx +11 -8
  93. package/src/ui/list-row.tsx +232 -0
  94. package/src/ui/loading-state.tsx +215 -0
  95. package/src/ui/popover.tsx +56 -23
  96. package/src/ui/progress.tsx +28 -16
  97. package/src/ui/refresh-spin-icon.tsx +41 -0
  98. package/src/ui/search-input.tsx +66 -15
  99. package/src/ui/select.tsx +171 -100
  100. package/src/ui/separator.tsx +23 -14
  101. package/src/ui/slider.tsx +21 -7
  102. package/src/ui/sonner.tsx +68 -30
  103. package/src/ui/spinner.tsx +229 -11
  104. package/src/ui/status-dot.tsx +84 -0
  105. package/src/ui/surface.tsx +49 -0
  106. package/src/ui/switch.tsx +29 -15
  107. package/src/ui/table.tsx +38 -16
  108. package/src/ui/tabs.tsx +123 -35
  109. package/src/ui/tabsSliding.ts +33 -1
  110. package/src/ui/textarea.tsx +13 -4
  111. package/src/ui/tooltip.tsx +50 -14
  112. package/src/ui/ui-config.tsx +149 -0
  113. package/src/utils/cat-color.ts +123 -0
  114. package/src/utils/dayjs.ts +6 -0
  115. package/src/utils/gesture.ts +59 -0
  116. package/src/utils/runtimeVisibility.ts +167 -0
  117. package/src/utils/sharedClock.ts +96 -0
  118. package/src/utils/surface-radius.ts +16 -0
  119. package/src/utils/useDragSensors.ts +58 -0
  120. package/tokens/examples/tokens-moved/Fixture.tsx +283 -0
  121. package/tokens/examples/tokens-moved/README.md +20 -0
  122. package/tokens/examples/tokens-moved/index.html +12 -0
  123. package/tokens/examples/tokens-moved/main.tsx +6 -0
  124. package/tokens/examples/tokens-moved/package.json +14 -0
  125. package/tokens/examples/tokens-moved/styles.css +12 -0
  126. package/tokens/examples/tokens-moved/tsconfig.json +14 -0
  127. package/tokens/examples/tokens-moved/vite.config.ts +11 -0
  128. package/tokens/src/css/border-beam.css +116 -0
  129. package/tokens/src/css/compat-shadcn-rgb.css +6 -0
  130. package/tokens/src/css/markdown.css +318 -0
@@ -0,0 +1,199 @@
1
+ import type { ActivityStep } from "./activity-shared";
2
+
3
+ /**
4
+ * One row in the activity timeline. Subtask rows may nest child rows that ran
5
+ * inside that agent (keyed by parentToolUseId → toolUseId).
6
+ */
7
+ export interface ActivityRow {
8
+ step: ActivityStep;
9
+ children?: ActivityRow[];
10
+ }
11
+
12
+ /**
13
+ * Status-filler thinking labels emitted by older callback versions (and by
14
+ * prod until the current callback deploys). The response/reasoning text is
15
+ * shown directly, so these narration rows are pure noise — hide them.
16
+ */
17
+ const LEGACY_NOISE_LABELS = new Set([
18
+ "Generating response...",
19
+ "Generated response",
20
+ "Streaming response...",
21
+ "Streamed response",
22
+ "Finalizing response...",
23
+ ]);
24
+
25
+ /** Thinking labels that mark model reasoning rather than status narration. */
26
+ const REASONING_LABELS = new Set(["Thinking...", "Thought"]);
27
+
28
+ /** Placeholder details older callbacks attached to reasoning-label steps. */
29
+ const FILLER_DETAILS = new Set([
30
+ "Claude is reasoning...",
31
+ "Codex is reasoning...",
32
+ "Opencode is reasoning...",
33
+ "Cursor is reasoning...",
34
+ "Receiving reply...",
35
+ ]);
36
+
37
+ /**
38
+ * Older callbacks stored reasoning as thinking steps labelled
39
+ * "Thinking..."/"Thought". Remap those with real text to reasoning blocks;
40
+ * drop the bare placeholder ones (nothing to show).
41
+ */
42
+ export function normalizeStep(step: ActivityStep): ActivityStep | null {
43
+ if (step.type !== "thinking") return step;
44
+ if (LEGACY_NOISE_LABELS.has(step.label)) return null;
45
+ if (REASONING_LABELS.has(step.label)) {
46
+ if (step.detail && !FILLER_DETAILS.has(step.detail)) {
47
+ return { ...step, type: "reasoning" };
48
+ }
49
+ return null;
50
+ }
51
+ return step;
52
+ }
53
+
54
+ /** Builds one row per normalized step (no consecutive-type merging). */
55
+ function stepsToRows(steps: ActivityStep[]): ActivityRow[] {
56
+ const rows: ActivityRow[] = [];
57
+ for (const raw of steps) {
58
+ const step = normalizeStep(raw);
59
+ if (!step) continue;
60
+ rows.push({ step });
61
+ }
62
+ return rows;
63
+ }
64
+
65
+ /**
66
+ * Row types that read as narration rather than work: they already summarise
67
+ * themselves, so folding them into an action group would hide their only text.
68
+ */
69
+ const STANDALONE_TYPES = new Set<ActivityStep["type"]>([
70
+ "todos",
71
+ "notice",
72
+ "status",
73
+ "question",
74
+ "steer",
75
+ ]);
76
+
77
+ /** One block in the activity timeline: prose, a lone row, or a folded run. */
78
+ export type ActivitySegment =
79
+ | { kind: "reasoning"; step: ActivityStep }
80
+ | { kind: "response"; step: ActivityStep }
81
+ | { kind: "row"; row: ActivityRow }
82
+ | { kind: "actions"; rows: ActivityRow[] };
83
+
84
+ /**
85
+ * Folds rows into the read-then-act rhythm of the turn: each reasoning block
86
+ * stays prose, and the run of tool calls it produced collapses behind a single
87
+ * summary line. Without this the whole turn is one undifferentiated wall of
88
+ * per-call rows and the thinking that motivated them is lost in it.
89
+ */
90
+ export function groupActivityRows(rows: ActivityRow[]): ActivitySegment[] {
91
+ const segments: ActivitySegment[] = [];
92
+
93
+ for (const row of rows) {
94
+ if (row.step.type === "reasoning") {
95
+ segments.push({ kind: "reasoning", step: row.step });
96
+ continue;
97
+ }
98
+ // Mid-turn reply text: it ends the tool run before it, like reasoning.
99
+ if (row.step.type === "response") {
100
+ segments.push({ kind: "response", step: row.step });
101
+ continue;
102
+ }
103
+ if (STANDALONE_TYPES.has(row.step.type)) {
104
+ segments.push({ kind: "row", row });
105
+ continue;
106
+ }
107
+ const last = segments.at(-1);
108
+ if (last?.kind === "actions") {
109
+ last.rows.push(row);
110
+ continue;
111
+ }
112
+ segments.push({ kind: "actions", rows: [row] });
113
+ }
114
+
115
+ return segments;
116
+ }
117
+
118
+ /**
119
+ * React key for one activity step. `label` and `status` are omitted so a
120
+ * streaming update (Running → Ran, error → recovered) keeps the same instance.
121
+ * `toolUseId` is the identity the callback already stamps; the fallback is
122
+ * type + path/command + occurrence in the list being keyed (never the visible
123
+ * overflow slice — callers must pass the full-list index).
124
+ */
125
+ export function activityStepKey(
126
+ step: ActivityStep,
127
+ occurrence: number,
128
+ ): string {
129
+ const id = step.toolUseId;
130
+ if (id !== undefined && id.length > 0) {
131
+ return `id:${id}`;
132
+ }
133
+ const stable = step.path ?? step.command ?? "";
134
+ return `fb:${step.type}:${stable}:${occurrence}`;
135
+ }
136
+
137
+ export function activityRowKey(row: ActivityRow, occurrence: number): string {
138
+ return activityStepKey(row.step, occurrence);
139
+ }
140
+
141
+ /** React key for a timeline segment. Action groups key off the first row. */
142
+ export function activitySegmentKey(
143
+ segment: ActivitySegment,
144
+ occurrence: number,
145
+ ): string {
146
+ if (segment.kind === "reasoning" || segment.kind === "response") {
147
+ return `${segment.kind}:${activityStepKey(segment.step, occurrence)}`;
148
+ }
149
+ if (segment.kind === "row") {
150
+ return `row:${activityRowKey(segment.row, occurrence)}`;
151
+ }
152
+ const first = segment.rows[0];
153
+ if (first === undefined) {
154
+ return `actions:${occurrence}`;
155
+ }
156
+ return `actions:${activityRowKey(first, occurrence)}`;
157
+ }
158
+
159
+ /**
160
+ * Builds per-call activity rows. Steps with `parentToolUseId` nest under the
161
+ * matching subtask `toolUseId`. Orphans whose parent was never found append
162
+ * at the top level (never drop).
163
+ */
164
+ export function buildActivityRows(steps: ActivityStep[]): ActivityRow[] {
165
+ const childrenByParent = new Map<string, ActivityStep[]>();
166
+ const topLevel: ActivityStep[] = [];
167
+
168
+ for (const step of steps) {
169
+ const parentId = step.parentToolUseId;
170
+ if (parentId) {
171
+ const existing = childrenByParent.get(parentId);
172
+ if (existing) existing.push(step);
173
+ else childrenByParent.set(parentId, [step]);
174
+ } else {
175
+ topLevel.push(step);
176
+ }
177
+ }
178
+
179
+ const rows = stepsToRows(topLevel);
180
+ const attached = new Set<string>();
181
+
182
+ for (const row of rows) {
183
+ if (row.step.type !== "subtask") continue;
184
+ const toolUseId = row.step.toolUseId;
185
+ if (!toolUseId) continue;
186
+ const kids = childrenByParent.get(toolUseId);
187
+ if (kids && kids.length > 0) {
188
+ row.children = stepsToRows(kids);
189
+ attached.add(toolUseId);
190
+ }
191
+ }
192
+
193
+ for (const [parentId, kids] of childrenByParent) {
194
+ if (attached.has(parentId)) continue;
195
+ rows.push(...stepsToRows(kids));
196
+ }
197
+
198
+ return rows;
199
+ }