@ciridae/ui 0.2.5 → 0.3.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 (126) hide show
  1. package/dist/components/ui/item.d.ts +1 -1
  2. package/dist/styled-system/styles.css +393 -61
  3. package/dist/styles.css +2 -0
  4. package/package.json +2 -260
  5. package/dist/components/agentic/agent-card.d.ts +0 -28
  6. package/dist/components/agentic/agent-card.js +0 -27
  7. package/dist/components/agentic/agent-composer.d.ts +0 -44
  8. package/dist/components/agentic/agent-composer.js +0 -104
  9. package/dist/components/agentic/agent-context.d.ts +0 -28
  10. package/dist/components/agentic/agent-context.js +0 -102
  11. package/dist/components/agentic/agent-plan.d.ts +0 -27
  12. package/dist/components/agentic/agent-plan.js +0 -43
  13. package/dist/components/agentic/agent-queue.d.ts +0 -46
  14. package/dist/components/agentic/agent-queue.js +0 -53
  15. package/dist/components/agentic/agent-task.d.ts +0 -16
  16. package/dist/components/agentic/agent-task.js +0 -20
  17. package/dist/components/agentic/approval-request.d.ts +0 -24
  18. package/dist/components/agentic/approval-request.js +0 -57
  19. package/dist/components/agentic/artifact.d.ts +0 -24
  20. package/dist/components/agentic/artifact.js +0 -72
  21. package/dist/components/agentic/attachments.d.ts +0 -124
  22. package/dist/components/agentic/attachments.js +0 -595
  23. package/dist/components/agentic/audio-player.d.ts +0 -16
  24. package/dist/components/agentic/audio-player.js +0 -21
  25. package/dist/components/agentic/canvas.d.ts +0 -10
  26. package/dist/components/agentic/canvas.js +0 -22
  27. package/dist/components/agentic/clipboard.d.ts +0 -2
  28. package/dist/components/agentic/clipboard.js +0 -12
  29. package/dist/components/agentic/code-block.d.ts +0 -43
  30. package/dist/components/agentic/code-block.js +0 -92
  31. package/dist/components/agentic/commit.d.ts +0 -57
  32. package/dist/components/agentic/commit.js +0 -85
  33. package/dist/components/agentic/connection.d.ts +0 -3
  34. package/dist/components/agentic/connection.js +0 -8
  35. package/dist/components/agentic/controls.d.ts +0 -6
  36. package/dist/components/agentic/controls.js +0 -7
  37. package/dist/components/agentic/conversation.d.ts +0 -25
  38. package/dist/components/agentic/conversation.js +0 -56
  39. package/dist/components/agentic/edge.d.ts +0 -8
  40. package/dist/components/agentic/edge.js +0 -65
  41. package/dist/components/agentic/effort-selector.d.ts +0 -43
  42. package/dist/components/agentic/effort-selector.js +0 -47
  43. package/dist/components/agentic/environment-variables.d.ts +0 -32
  44. package/dist/components/agentic/environment-variables.js +0 -66
  45. package/dist/components/agentic/file-tree.d.ts +0 -24
  46. package/dist/components/agentic/file-tree.js +0 -56
  47. package/dist/components/agentic/image.d.ts +0 -9
  48. package/dist/components/agentic/image.js +0 -11
  49. package/dist/components/agentic/inline-citation.d.ts +0 -40
  50. package/dist/components/agentic/inline-citation.js +0 -111
  51. package/dist/components/agentic/jsx-preview.d.ts +0 -19
  52. package/dist/components/agentic/jsx-preview.js +0 -34
  53. package/dist/components/agentic/message-branch.d.ts +0 -20
  54. package/dist/components/agentic/message-branch.js +0 -83
  55. package/dist/components/agentic/message-response.css +0 -265
  56. package/dist/components/agentic/message-response.css.d.ts +0 -2
  57. package/dist/components/agentic/message.d.ts +0 -27
  58. package/dist/components/agentic/message.js +0 -57
  59. package/dist/components/agentic/mic-selector.d.ts +0 -58
  60. package/dist/components/agentic/mic-selector.js +0 -173
  61. package/dist/components/agentic/model-selector.d.ts +0 -39
  62. package/dist/components/agentic/model-selector.js +0 -47
  63. package/dist/components/agentic/node.d.ts +0 -26
  64. package/dist/components/agentic/node.js +0 -29
  65. package/dist/components/agentic/open-in-chat.d.ts +0 -9
  66. package/dist/components/agentic/open-in-chat.js +0 -8
  67. package/dist/components/agentic/package-info.d.ts +0 -30
  68. package/dist/components/agentic/package-info.js +0 -44
  69. package/dist/components/agentic/panel.d.ts +0 -6
  70. package/dist/components/agentic/panel.js +0 -7
  71. package/dist/components/agentic/persona.d.ts +0 -16
  72. package/dist/components/agentic/persona.js +0 -116
  73. package/dist/components/agentic/prompt-input-action-menu.d.ts +0 -16
  74. package/dist/components/agentic/prompt-input-action-menu.js +0 -22
  75. package/dist/components/agentic/prompt-input-command.d.ts +0 -18
  76. package/dist/components/agentic/prompt-input-command.js +0 -25
  77. package/dist/components/agentic/prompt-input-hover-card.d.ts +0 -10
  78. package/dist/components/agentic/prompt-input-hover-card.js +0 -13
  79. package/dist/components/agentic/prompt-input-select.d.ts +0 -14
  80. package/dist/components/agentic/prompt-input-select.js +0 -19
  81. package/dist/components/agentic/prompt-input-tabs.d.ts +0 -17
  82. package/dist/components/agentic/prompt-input-tabs.js +0 -45
  83. package/dist/components/agentic/prompt-input.d.ts +0 -79
  84. package/dist/components/agentic/prompt-input.js +0 -206
  85. package/dist/components/agentic/reasoning.d.ts +0 -21
  86. package/dist/components/agentic/reasoning.js +0 -106
  87. package/dist/components/agentic/run-checkpoint.d.ts +0 -13
  88. package/dist/components/agentic/run-checkpoint.js +0 -19
  89. package/dist/components/agentic/run-trace.d.ts +0 -30
  90. package/dist/components/agentic/run-trace.js +0 -56
  91. package/dist/components/agentic/sandbox.d.ts +0 -24
  92. package/dist/components/agentic/sandbox.js +0 -33
  93. package/dist/components/agentic/schema-display.d.ts +0 -39
  94. package/dist/components/agentic/schema-display.js +0 -56
  95. package/dist/components/agentic/shimmer.d.ts +0 -11
  96. package/dist/components/agentic/shimmer.js +0 -16
  97. package/dist/components/agentic/snippet.d.ts +0 -18
  98. package/dist/components/agentic/snippet.js +0 -35
  99. package/dist/components/agentic/sources.d.ts +0 -16
  100. package/dist/components/agentic/sources.js +0 -17
  101. package/dist/components/agentic/speech-input.d.ts +0 -24
  102. package/dist/components/agentic/speech-input.js +0 -30
  103. package/dist/components/agentic/stack-trace.d.ts +0 -27
  104. package/dist/components/agentic/stack-trace.js +0 -76
  105. package/dist/components/agentic/suggestion.d.ts +0 -12
  106. package/dist/components/agentic/suggestion.js +0 -15
  107. package/dist/components/agentic/terminal.d.ts +0 -24
  108. package/dist/components/agentic/terminal.js +0 -47
  109. package/dist/components/agentic/test-results.d.ts +0 -51
  110. package/dist/components/agentic/test-results.js +0 -83
  111. package/dist/components/agentic/theme.d.ts +0 -5
  112. package/dist/components/agentic/theme.js +0 -31
  113. package/dist/components/agentic/tool.d.ts +0 -25
  114. package/dist/components/agentic/tool.js +0 -73
  115. package/dist/components/agentic/toolbar.d.ts +0 -6
  116. package/dist/components/agentic/toolbar.js +0 -7
  117. package/dist/components/agentic/transcription.d.ts +0 -20
  118. package/dist/components/agentic/transcription.js +0 -32
  119. package/dist/components/agentic/types.d.ts +0 -172
  120. package/dist/components/agentic/types.js +0 -1
  121. package/dist/components/agentic/use-controllable-state.d.ts +0 -6
  122. package/dist/components/agentic/use-controllable-state.js +0 -13
  123. package/dist/components/agentic/voice-selector.d.ts +0 -69
  124. package/dist/components/agentic/voice-selector.js +0 -122
  125. package/dist/components/agentic/web-preview.d.ts +0 -25
  126. package/dist/components/agentic/web-preview.js +0 -33
@@ -1,265 +0,0 @@
1
- @import "katex/dist/katex.min.css";
2
-
3
- @keyframes sd-fade-in {
4
- from {
5
- opacity: 0;
6
- }
7
- to {
8
- opacity: 1;
9
- }
10
- }
11
-
12
- @keyframes sd-blur-in {
13
- from {
14
- filter: blur(4px);
15
- opacity: 0;
16
- }
17
- to {
18
- filter: blur(0);
19
- opacity: 1;
20
- }
21
- }
22
-
23
- @keyframes sd-slide-up {
24
- from {
25
- opacity: 0;
26
- transform: translateY(4px);
27
- }
28
- to {
29
- opacity: 1;
30
- transform: translateY(0);
31
- }
32
- }
33
-
34
- [data-sd-animate] {
35
- animation: var(--sd-animation, sd-fade-in) var(--sd-duration, var(--motion-duration-fast))
36
- var(--sd-easing, var(--motion-ease-standard)) var(--sd-delay, 0ms) both;
37
- }
38
-
39
- .agentic-message-response {
40
- color: var(--foreground);
41
- font-size: 0.875rem;
42
- line-height: 1.6;
43
- max-width: 100%;
44
- min-width: 0;
45
- overflow-wrap: anywhere;
46
- }
47
-
48
- .agentic-message-response :where(h1, h2, h3, h4, h5, h6) {
49
- color: var(--foreground);
50
- font-family: var(--font-ciridae-display);
51
- font-weight: var(--font-ciridae-heading-weight);
52
- letter-spacing: 0;
53
- line-height: 1.2;
54
- margin-block: 1.25rem 0.5rem;
55
- }
56
-
57
- .agentic-message-response :where(h1) {
58
- font-size: 1.35rem;
59
- }
60
-
61
- .agentic-message-response :where(h2) {
62
- font-size: 1.2rem;
63
- }
64
-
65
- .agentic-message-response :where(h3) {
66
- font-size: 1.05rem;
67
- }
68
-
69
- .agentic-message-response :where(h4, h5, h6) {
70
- font-size: 0.95rem;
71
- }
72
-
73
- .agentic-message-response :where(p) {
74
- margin-block: 0.75rem;
75
- }
76
-
77
- .agentic-message-response :where(ul, ol) {
78
- margin-block: 0.75rem;
79
- padding-inline-start: 1.25rem;
80
- }
81
-
82
- .agentic-message-response :where(ul) {
83
- list-style: disc;
84
- }
85
-
86
- .agentic-message-response :where(ol) {
87
- list-style: decimal;
88
- }
89
-
90
- .agentic-message-response :where(li) {
91
- margin-block: 0.25rem;
92
- padding-inline-start: 0.125rem;
93
- }
94
-
95
- .agentic-message-response :where(a) {
96
- color: var(--foreground);
97
- text-decoration-color: color-mix(in oklch, var(--foreground) 36%, transparent);
98
- text-decoration-line: underline;
99
- text-underline-offset: 0.18em;
100
- }
101
-
102
- .agentic-message-response :where(a:hover) {
103
- text-decoration-color: var(--foreground);
104
- }
105
-
106
- .agentic-message-response :where(strong) {
107
- font-weight: var(--font-ciridae-strong-weight);
108
- }
109
-
110
- .agentic-message-response :where(hr) {
111
- border: 0;
112
- border-block-start: 1px solid var(--border);
113
- margin-block: 1rem;
114
- }
115
-
116
- .agentic-message-response :where(blockquote) {
117
- border-inline-start: 2px solid var(--border);
118
- color: var(--muted-foreground);
119
- font-style: normal;
120
- margin-block: 1rem;
121
- padding-inline-start: 0.875rem;
122
- }
123
-
124
- .agentic-message-response :where(code),
125
- .agentic-message-response :where(kbd),
126
- .agentic-message-response :where(pre) {
127
- font-family: var(--font-ciridae-mono);
128
- font-variant-numeric: tabular-nums;
129
- }
130
-
131
- .agentic-message-response :where(:not(pre) > code),
132
- .agentic-message-response [data-streamdown="inline-code"] {
133
- background: var(--muted);
134
- border: 1px solid color-mix(in oklch, var(--border) 72%, transparent);
135
- border-radius: var(--radius-sm);
136
- color: var(--foreground);
137
- font-size: 0.8125rem;
138
- padding: 0.0625rem 0.3125rem;
139
- }
140
-
141
- .agentic-message-response [data-streamdown="code-block"],
142
- .agentic-message-response [data-streamdown="mermaid-block"] {
143
- background: color-mix(in oklch, var(--muted) 52%, transparent);
144
- border: 1px solid var(--border);
145
- border-radius: var(--radius-lg);
146
- box-shadow: var(--shadow-xs);
147
- margin-block: 1rem;
148
- max-width: 100%;
149
- overflow: hidden;
150
- padding: 0.5rem;
151
- }
152
-
153
- .agentic-message-response [data-streamdown="code-block-header"] {
154
- color: var(--muted-foreground);
155
- font-size: 0.75rem;
156
- height: 1.75rem;
157
- line-height: 1.75rem;
158
- }
159
-
160
- .agentic-message-response [data-streamdown="code-block-body"] {
161
- background: var(--background);
162
- border: 1px solid color-mix(in oklch, var(--border) 72%, transparent);
163
- border-radius: var(--radius-md);
164
- font-size: 0.8125rem;
165
- line-height: 1.55;
166
- overflow-x: auto;
167
- padding: 0.875rem;
168
- }
169
-
170
- .agentic-message-response [data-streamdown="code-block-body"] pre {
171
- background: transparent;
172
- margin: 0;
173
- }
174
-
175
- .agentic-message-response [data-streamdown="code-block-actions"],
176
- .agentic-message-response [data-streamdown="mermaid-block-actions"] {
177
- align-items: center;
178
- background: color-mix(in oklch, var(--background) 88%, transparent);
179
- border: 1px solid var(--border);
180
- border-radius: var(--radius-md);
181
- gap: 0.125rem;
182
- min-height: 1.75rem;
183
- padding: 0.125rem;
184
- transform: translateY(-0.625rem);
185
- }
186
-
187
- .agentic-message-response [data-streamdown="code-block-copy-button"],
188
- .agentic-message-response [data-streamdown="code-block-download-button"],
189
- .agentic-message-response [data-streamdown="table-copy-button"],
190
- .agentic-message-response [data-streamdown="table-download-button"],
191
- .agentic-message-response [data-streamdown="mermaid-copy-button"],
192
- .agentic-message-response [data-streamdown="mermaid-download-button"] {
193
- align-items: center;
194
- color: var(--muted-foreground);
195
- display: inline-flex;
196
- height: 1.5rem;
197
- justify-content: center;
198
- transition:
199
- background-color var(--motion-duration-fast) var(--motion-ease-standard),
200
- color var(--motion-duration-fast) var(--motion-ease-standard);
201
- width: 1.5rem;
202
- }
203
-
204
- .agentic-message-response [data-streamdown="code-block-copy-button"]:hover,
205
- .agentic-message-response [data-streamdown="code-block-download-button"]:hover,
206
- .agentic-message-response [data-streamdown="table-copy-button"]:hover,
207
- .agentic-message-response [data-streamdown="table-download-button"]:hover,
208
- .agentic-message-response [data-streamdown="mermaid-copy-button"]:hover,
209
- .agentic-message-response [data-streamdown="mermaid-download-button"]:hover {
210
- background: var(--accent);
211
- color: var(--accent-foreground);
212
- }
213
-
214
- .agentic-message-response :where(table) {
215
- border: 1px solid var(--border);
216
- border-collapse: separate;
217
- border-radius: var(--radius-md);
218
- border-spacing: 0;
219
- display: block;
220
- margin-block: 1rem;
221
- max-width: 100%;
222
- overflow-x: auto;
223
- width: max-content;
224
- }
225
-
226
- .agentic-message-response :where(thead) {
227
- background: var(--muted);
228
- color: var(--table-header-foreground);
229
- }
230
-
231
- .agentic-message-response :where(th, td) {
232
- border-block-end: 1px solid var(--border);
233
- font-size: 0.8125rem;
234
- padding: 0.5rem 0.625rem;
235
- text-align: start;
236
- vertical-align: top;
237
- }
238
-
239
- .agentic-message-response :where(th) {
240
- font-weight: var(--font-ciridae-metadata-weight);
241
- }
242
-
243
- .agentic-message-response :where(tr:last-child td) {
244
- border-block-end: 0;
245
- }
246
-
247
- .agentic-message-response :where(.katex-display) {
248
- overflow-x: auto;
249
- overflow-y: hidden;
250
- padding-block: 0.25rem;
251
- }
252
-
253
- .agentic-message-response [data-streamdown="mermaid"] {
254
- background: var(--background);
255
- border: 1px solid color-mix(in oklch, var(--border) 72%, transparent);
256
- border-radius: var(--radius-md);
257
- color: var(--foreground);
258
- padding: 1rem;
259
- }
260
-
261
- @media (prefers-reduced-motion: reduce) {
262
- .agentic-message-response [data-sd-animate] {
263
- animation: none !important;
264
- }
265
- }
@@ -1,2 +0,0 @@
1
- declare const stylesheet: string;
2
- export default stylesheet;
@@ -1,27 +0,0 @@
1
- import type * as React from "react";
2
- import { Streamdown } from "streamdown";
3
- import { MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, type MessageBranchContentProps, type MessageBranchNextProps, type MessageBranchPageProps, type MessageBranchPreviousProps, type MessageBranchProps, type MessageBranchSelectorProps } from "@ciridae/ui/message-branch";
4
- import type { AgenticMessageRole } from "@ciridae/ui/types";
5
- import "@ciridae/ui/message-response.css";
6
- import { Button } from "@ciridae/ui/button";
7
- type MessageProps = React.ComponentProps<"div"> & {
8
- role: AgenticMessageRole;
9
- };
10
- type MessageContentProps = React.ComponentProps<"div"> & {
11
- variant?: "default" | "bubble";
12
- };
13
- type MessageActionsProps = React.ComponentProps<"div">;
14
- type MessageActionProps = React.ComponentProps<typeof Button> & {
15
- label?: string;
16
- tooltip?: string;
17
- };
18
- type MessageToolbarProps = React.ComponentProps<"div">;
19
- type MessageResponseProps = React.ComponentProps<typeof Streamdown>;
20
- declare function Message({ className, role, ...props }: MessageProps): React.JSX.Element;
21
- declare function MessageContent({ className, variant, ...props }: MessageContentProps): React.JSX.Element;
22
- declare function MessageActions({ className, ...props }: MessageActionsProps): React.JSX.Element;
23
- declare function MessageAction({ children, label, tooltip, variant, size, ...props }: MessageActionProps): React.JSX.Element;
24
- declare const MessageResponse: React.MemoExoticComponent<({ animated, className, plugins, ...props }: MessageResponseProps) => React.JSX.Element>;
25
- declare function MessageToolbar({ className, ...props }: MessageToolbarProps): React.JSX.Element;
26
- export { Message, MessageAction, MessageActions, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageResponse, MessageToolbar, };
27
- export type { MessageActionProps, MessageActionsProps, MessageBranchContentProps, MessageBranchNextProps, MessageBranchPageProps, MessageBranchPreviousProps, MessageBranchProps, MessageBranchSelectorProps, MessageContentProps, MessageProps, MessageResponseProps, MessageToolbarProps, };
@@ -1,57 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cjk } from "@streamdown/cjk";
3
- import { code } from "@streamdown/code";
4
- import { math } from "@streamdown/math";
5
- import { mermaid } from "@streamdown/mermaid";
6
- import { memo, useEffect, useState } from "react";
7
- import { Streamdown } from "streamdown";
8
- import { MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, } from "@ciridae/ui/message-branch";
9
- import "@ciridae/ui/message-response.css";
10
- import { Button } from "@ciridae/ui/button";
11
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@ciridae/ui/tooltip";
12
- import { cn } from "@ciridae/ui/utils";
13
- const streamdownPlugins = { cjk, code, math, mermaid };
14
- const messageResponseAnimation = {
15
- animation: "fade-in",
16
- duration: 200,
17
- easing: "var(--motion-ease-standard)",
18
- sep: "word",
19
- };
20
- function Message({ className, role, ...props }) {
21
- return (_jsx("div", { "data-role": role, "data-slot": "message", className: cn("group/message flex w-full flex-col gap-2", role === "user" ? "items-end" : "items-start", role === "system" ? "py-1" : undefined, className), ...props }));
22
- }
23
- function MessageContent({ className, variant = "default", ...props }) {
24
- return (_jsx("div", { "data-slot": "message-content", "data-variant": variant, className: cn("min-w-0 max-w-[min(42rem,100%)] text-sm leading-relaxed", "data-[variant=bubble]:rounded-lg data-[variant=bubble]:border data-[variant=bubble]:bg-card data-[variant=bubble]:px-4 data-[variant=bubble]:py-3 data-[variant=bubble]:text-card-foreground data-[variant=bubble]:shadow-xs", "group-data-[role=user]/message:max-w-[min(34rem,78%)] group-data-[role=user]/message:rounded-lg group-data-[role=user]/message:border group-data-[role=user]/message:bg-secondary group-data-[role=user]/message:px-4 group-data-[role=user]/message:py-3 group-data-[role=user]/message:text-secondary-foreground group-data-[role=user]/message:shadow-xs", "group-data-[role=assistant]/message:text-foreground", "group-data-[role=system]/message:max-w-full group-data-[role=system]/message:rounded-md group-data-[role=system]/message:border group-data-[role=system]/message:bg-muted/30 group-data-[role=system]/message:px-3 group-data-[role=system]/message:py-2 group-data-[role=system]/message:text-xs group-data-[role=system]/message:text-muted-foreground", className), ...props }));
25
- }
26
- function MessageActions({ className, ...props }) {
27
- return (_jsx("div", { "data-slot": "message-actions", className: cn("flex items-center gap-1", className), ...props }));
28
- }
29
- function MessageAction({ children, label, tooltip, variant = "ghost", size = "icon-sm", ...props }) {
30
- const accessibleLabel = props["aria-label"] ?? label ?? tooltip;
31
- const button = (_jsxs(Button, { "aria-label": accessibleLabel, size: size, type: "button", variant: variant, ...props, children: [children, label || tooltip ? _jsx("span", { className: "sr-only", children: label ?? tooltip }) : null] }));
32
- if (!tooltip)
33
- return button;
34
- return (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: button }), _jsx(TooltipContent, { children: _jsx("p", { children: tooltip }) })] }) }));
35
- }
36
- const MessageResponse = memo(function MessageResponse({ animated, className, plugins, ...props }) {
37
- const prefersReducedMotion = usePrefersReducedMotion();
38
- const resolvedAnimation = animated === true ? messageResponseAnimation : animated;
39
- return (_jsx(Streamdown, { animated: prefersReducedMotion ? false : resolvedAnimation, className: cn("agentic-message-response", className), plugins: { ...streamdownPlugins, ...plugins }, ...props }));
40
- });
41
- MessageResponse.displayName = "MessageResponse";
42
- function usePrefersReducedMotion() {
43
- const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
44
- useEffect(() => {
45
- if (typeof window === "undefined")
46
- return;
47
- const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
48
- const handleChange = (event) => setPrefersReducedMotion(event.matches);
49
- mediaQuery.addEventListener("change", handleChange);
50
- return () => mediaQuery.removeEventListener("change", handleChange);
51
- }, []);
52
- return prefersReducedMotion;
53
- }
54
- function MessageToolbar({ className, ...props }) {
55
- return (_jsx("div", { "data-slot": "message-toolbar", className: cn("mt-1 flex w-full max-w-[min(42rem,100%)] items-center justify-between gap-3", "group-data-[role=user]/message:ml-auto group-data-[role=system]/message:max-w-full", className), ...props }));
56
- }
57
- export { Message, MessageAction, MessageActions, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageResponse, MessageToolbar, };
@@ -1,58 +0,0 @@
1
- import * as React from "react";
2
- import type { AgenticMicOption } from "@ciridae/ui/types";
3
- import { CommandEmpty, CommandInput, CommandItem, CommandList } from "@ciridae/ui/command";
4
- import { Popover, PopoverContent, PopoverTrigger } from "@ciridae/ui/popover";
5
- type MicSelectorContextValue = {
6
- data: AgenticMicOption[];
7
- open: boolean;
8
- setOpen: (open: boolean) => void;
9
- setValue: (value: string | undefined) => void;
10
- setWidth: (width: number) => void;
11
- value: string | undefined;
12
- width: number;
13
- };
14
- type MicSelectorProps = React.ComponentProps<typeof Popover> & {
15
- defaultValue?: string;
16
- mics?: AgenticMicOption[];
17
- onValueChange?: (value: string | undefined) => void;
18
- value?: string;
19
- };
20
- type MicSelectorTriggerProps = React.ComponentProps<typeof PopoverTrigger>;
21
- type MicSelectorContentProps = React.ComponentProps<typeof PopoverContent> & {
22
- popoverOptions?: React.ComponentProps<typeof PopoverContent>;
23
- };
24
- type MicSelectorInputProps = React.ComponentProps<typeof CommandInput>;
25
- type MicSelectorListProps = Omit<React.ComponentProps<typeof CommandList>, "children"> & {
26
- children: (mics: AgenticMicOption[]) => React.ReactNode;
27
- };
28
- type MicSelectorEmptyProps = React.ComponentProps<typeof CommandEmpty>;
29
- type MicSelectorItemProps = React.ComponentProps<typeof CommandItem> & {
30
- mic?: AgenticMicOption;
31
- };
32
- type MicSelectorLabelProps = React.ComponentProps<"span"> & {
33
- mic: AgenticMicOption;
34
- };
35
- type MicSelectorValueProps = React.ComponentProps<"span"> & {
36
- placeholder?: string;
37
- };
38
- declare function MicSelector({ children, defaultOpen, defaultValue, mics, onOpenChange, onValueChange, open: openProp, value: valueProp, ...props }: MicSelectorProps): React.JSX.Element;
39
- declare function useMicSelector(): MicSelectorContextValue;
40
- declare function useAudioDevices({ enabled }?: {
41
- enabled?: boolean;
42
- }): {
43
- devices: AgenticMicOption[];
44
- error: string | null;
45
- hasPermission: boolean;
46
- loadDevices: () => Promise<void>;
47
- loading: boolean;
48
- };
49
- declare function MicSelectorTrigger({ children, ...props }: MicSelectorTriggerProps): React.JSX.Element;
50
- declare function MicSelectorContent({ className, popoverOptions, style, ...props }: MicSelectorContentProps): React.JSX.Element;
51
- declare function MicSelectorInput(props: MicSelectorInputProps): React.JSX.Element;
52
- declare function MicSelectorList({ children, ...props }: MicSelectorListProps): React.JSX.Element;
53
- declare function MicSelectorEmpty({ children, ...props }: MicSelectorEmptyProps): React.JSX.Element;
54
- declare function MicSelectorItem({ children, mic, onSelect, value, ...props }: MicSelectorItemProps): React.JSX.Element;
55
- declare function MicSelectorLabel({ className, mic, ...props }: MicSelectorLabelProps): React.JSX.Element;
56
- declare function MicSelectorValue({ className, placeholder, ...props }: MicSelectorValueProps): React.JSX.Element;
57
- export { MicSelector, MicSelectorContent, MicSelectorEmpty, MicSelectorInput, MicSelectorItem, MicSelectorLabel, MicSelectorList, MicSelectorTrigger, MicSelectorValue, useAudioDevices, useMicSelector, };
58
- export type { MicSelectorContentProps, MicSelectorEmptyProps, MicSelectorInputProps, MicSelectorItemProps, MicSelectorLabelProps, MicSelectorListProps, MicSelectorProps, MicSelectorTriggerProps, MicSelectorValueProps, };
@@ -1,173 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- /* eslint-disable max-lines, react-refresh/only-export-components */
3
- import { ChevronsUpDownIcon } from "lucide-react";
4
- import * as React from "react";
5
- import { Button } from "@ciridae/ui/button";
6
- import { Command, CommandEmpty, CommandInput, CommandItem, CommandList, } from "@ciridae/ui/command";
7
- import { Popover, PopoverContent, PopoverTrigger } from "@ciridae/ui/popover";
8
- import { cn } from "@ciridae/ui/utils";
9
- import { useControllableState } from "./use-controllable-state";
10
- const deviceIdRegex = /\(([\da-fA-F]{4}:[\da-fA-F]{4})\)$/;
11
- const MicSelectorContext = React.createContext(null);
12
- function MicSelector({ children, defaultOpen = false, defaultValue, mics, onOpenChange, onValueChange, open: openProp, value: valueProp, ...props }) {
13
- const [value, setValue] = useControllableState({
14
- defaultValue,
15
- onChange: onValueChange,
16
- value: valueProp,
17
- });
18
- const [open, setOpen] = useControllableState({
19
- defaultValue: defaultOpen,
20
- onChange: onOpenChange,
21
- value: openProp,
22
- });
23
- const [width, setWidth] = React.useState(200);
24
- const audioDevices = useAudioDevices({ enabled: !mics });
25
- const { devices: detectedMics, hasPermission, loadDevices, loading: devicesLoading, } = audioDevices;
26
- const attemptedPermissionRef = React.useRef(false);
27
- React.useEffect(() => {
28
- if (open && !mics && !hasPermission && !devicesLoading && !attemptedPermissionRef.current) {
29
- attemptedPermissionRef.current = true;
30
- void loadDevices();
31
- }
32
- }, [devicesLoading, hasPermission, loadDevices, mics, open]);
33
- React.useEffect(() => {
34
- if (!open)
35
- attemptedPermissionRef.current = false;
36
- }, [open]);
37
- const contextValue = React.useMemo(() => ({
38
- data: mics ?? detectedMics,
39
- open,
40
- setOpen,
41
- setValue,
42
- setWidth,
43
- value,
44
- width,
45
- }), [detectedMics, mics, open, setOpen, setValue, value, width]);
46
- return (_jsx(MicSelectorContext.Provider, { value: contextValue, children: _jsx(Popover, { onOpenChange: setOpen, open: open, ...props, children: children ?? _jsx(MicSelectorDefaultContent, {}) }) }));
47
- }
48
- function MicSelectorDefaultContent() {
49
- return (_jsxs(_Fragment, { children: [_jsx(MicSelectorTrigger, { asChild: true, children: _jsxs(Button, { className: "w-64 justify-between", variant: "outline", children: [_jsx(MicSelectorValue, { className: "max-w-52 text-left" }), _jsx(ChevronsUpDownIcon, { className: "size-4 opacity-60" })] }) }), _jsxs(MicSelectorContent, { children: [_jsx(MicSelectorInput, { placeholder: "Search microphones..." }), _jsx(MicSelectorList, { children: (devices) => (_jsxs(_Fragment, { children: [_jsx(MicSelectorEmpty, { children: "No microphone found." }), devices.map((mic) => (_jsx(MicSelectorItem, { mic: mic }, mic.id)))] })) })] })] }));
50
- }
51
- function useMicSelector() {
52
- const context = React.useContext(MicSelectorContext);
53
- if (!context)
54
- throw new Error("MicSelector components must be used within MicSelector");
55
- return context;
56
- }
57
- function useAudioDevices({ enabled = true } = {}) {
58
- const [devices, setDevices] = React.useState([]);
59
- const [error, setError] = React.useState(null);
60
- const [hasPermission, setHasPermission] = React.useState(false);
61
- const [loading, setLoading] = React.useState(false);
62
- const loadDevicesWithoutPermission = React.useCallback(async () => {
63
- if (!enabled || !navigator.mediaDevices?.enumerateDevices)
64
- return;
65
- try {
66
- setLoading(true);
67
- setError(null);
68
- const deviceList = await navigator.mediaDevices.enumerateDevices();
69
- setDevices(deviceList.filter(isAudioInput).map(mediaDeviceToMicOption));
70
- }
71
- catch (caughtError) {
72
- setError(caughtError instanceof Error ? caughtError.message : "Failed to get audio devices");
73
- }
74
- finally {
75
- setLoading(false);
76
- }
77
- }, [enabled]);
78
- const loadDevices = React.useCallback(async () => {
79
- if (!enabled || !navigator.mediaDevices?.getUserMedia)
80
- return;
81
- try {
82
- setLoading(true);
83
- setError(null);
84
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
85
- for (const track of stream.getTracks())
86
- track.stop();
87
- const deviceList = await navigator.mediaDevices.enumerateDevices();
88
- setDevices(deviceList.filter(isAudioInput).map(mediaDeviceToMicOption));
89
- setHasPermission(true);
90
- }
91
- catch (caughtError) {
92
- setError(caughtError instanceof Error ? caughtError.message : "Failed to get audio devices");
93
- }
94
- finally {
95
- setLoading(false);
96
- }
97
- }, [enabled]);
98
- React.useEffect(() => {
99
- void loadDevicesWithoutPermission();
100
- }, [loadDevicesWithoutPermission]);
101
- React.useEffect(() => {
102
- if (!enabled || !navigator.mediaDevices?.addEventListener)
103
- return;
104
- const handleDeviceChange = () => {
105
- void (hasPermission ? loadDevices() : loadDevicesWithoutPermission());
106
- };
107
- navigator.mediaDevices.addEventListener("devicechange", handleDeviceChange);
108
- return () => navigator.mediaDevices.removeEventListener("devicechange", handleDeviceChange);
109
- }, [enabled, hasPermission, loadDevices, loadDevicesWithoutPermission]);
110
- return { devices, error, hasPermission, loadDevices, loading };
111
- }
112
- function MicSelectorTrigger({ children, ...props }) {
113
- const { setWidth } = useMicSelector();
114
- const ref = React.useRef(null);
115
- React.useEffect(() => {
116
- if (!ref.current)
117
- return;
118
- const resizeObserver = new ResizeObserver(([entry]) => {
119
- if (entry?.target instanceof HTMLElement)
120
- setWidth(entry.target.offsetWidth);
121
- });
122
- resizeObserver.observe(ref.current);
123
- return () => resizeObserver.disconnect();
124
- }, [setWidth]);
125
- return (_jsx(PopoverTrigger, { ref: ref, ...props, children: children }));
126
- }
127
- function MicSelectorContent({ className, popoverOptions, style, ...props }) {
128
- const { width } = useMicSelector();
129
- const { className: popoverClassName, style: popoverStyle, ...popoverContentOptions } = popoverOptions ?? {};
130
- return (_jsx(PopoverContent, { align: "start", ...popoverContentOptions, ...props, className: cn("p-0", popoverClassName, className), style: { ...popoverStyle, ...style, width }, children: _jsx(Command, { children: props.children }) }));
131
- }
132
- function MicSelectorInput(props) {
133
- return _jsx(CommandInput, { ...props });
134
- }
135
- function MicSelectorList({ children, ...props }) {
136
- const { data } = useMicSelector();
137
- return _jsx(CommandList, { ...props, children: children(data) });
138
- }
139
- function MicSelectorEmpty({ children = "No microphone found.", ...props }) {
140
- return _jsx(CommandEmpty, { ...props, children: children });
141
- }
142
- function MicSelectorItem({ children, mic, onSelect, value, ...props }) {
143
- const { setOpen, setValue } = useMicSelector();
144
- const itemValue = value ?? mic?.id;
145
- return (_jsx(CommandItem, { onSelect: (currentValue) => {
146
- setValue(itemValue ?? currentValue);
147
- setOpen(false);
148
- onSelect?.(currentValue);
149
- }, value: itemValue, ...props, children: children ?? (mic ? _jsx(MicSelectorLabel, { mic: mic }) : null) }));
150
- }
151
- function MicSelectorLabel({ className, mic, ...props }) {
152
- const matches = mic.label.match(deviceIdRegex);
153
- const deviceId = matches?.[1];
154
- const name = deviceId ? mic.label.replace(deviceIdRegex, "").trim() : mic.label;
155
- return (_jsxs("span", { className: cn("grid min-w-0 gap-0.5", className), ...props, children: [_jsx("span", { className: "truncate", children: name }), _jsx("span", { className: "truncate text-xs text-muted-foreground", children: mic.description ?? (deviceId ? `Device ${deviceId}` : "Audio input") })] }));
156
- }
157
- function MicSelectorValue({ className, placeholder = "Select microphone...", ...props }) {
158
- const { data, value } = useMicSelector();
159
- const currentDevice = data.find((device) => device.id === value);
160
- return (_jsx("span", { className: cn("truncate", className), ...props, children: currentDevice?.label ?? placeholder }));
161
- }
162
- function isAudioInput(device) {
163
- return device.kind === "audioinput";
164
- }
165
- function mediaDeviceToMicOption(device) {
166
- return {
167
- description: device.groupId ? `Group ${device.groupId.slice(0, 8)}` : undefined,
168
- id: device.deviceId,
169
- label: device.label || "Microphone",
170
- mediaType: device.kind,
171
- };
172
- }
173
- export { MicSelector, MicSelectorContent, MicSelectorEmpty, MicSelectorInput, MicSelectorItem, MicSelectorLabel, MicSelectorList, MicSelectorTrigger, MicSelectorValue, useAudioDevices, useMicSelector, };
@@ -1,39 +0,0 @@
1
- import type * as React from "react";
2
- import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@ciridae/ui/command";
3
- import { Dialog, DialogContent, DialogTrigger } from "@ciridae/ui/dialog";
4
- type ModelSelectorProps = React.ComponentProps<typeof Dialog>;
5
- type ModelSelectorTriggerProps = React.ComponentProps<typeof DialogTrigger>;
6
- type ModelSelectorContentProps = React.ComponentProps<typeof DialogContent> & {
7
- title?: React.ReactNode;
8
- };
9
- type ModelSelectorDialogProps = React.ComponentProps<typeof CommandDialog>;
10
- type ModelSelectorInputProps = React.ComponentProps<typeof CommandInput>;
11
- type ModelSelectorListProps = React.ComponentProps<typeof CommandList>;
12
- type ModelSelectorEmptyProps = React.ComponentProps<typeof CommandEmpty>;
13
- type ModelSelectorGroupProps = React.ComponentProps<typeof CommandGroup>;
14
- type ModelSelectorItemProps = React.ComponentProps<typeof CommandItem>;
15
- type ModelSelectorShortcutProps = React.ComponentProps<typeof CommandShortcut>;
16
- type ModelSelectorSeparatorProps = React.ComponentProps<typeof CommandSeparator>;
17
- type ModelSelectorLogoProps = Omit<React.ComponentProps<"img">, "alt" | "src"> & {
18
- alt?: string;
19
- provider: string;
20
- src?: string;
21
- };
22
- type ModelSelectorLogoGroupProps = React.ComponentProps<"div">;
23
- type ModelSelectorNameProps = React.ComponentProps<"span">;
24
- declare function ModelSelector(props: ModelSelectorProps): React.JSX.Element;
25
- declare function ModelSelectorTrigger(props: ModelSelectorTriggerProps): React.JSX.Element;
26
- declare function ModelSelectorContent({ children, className, title, ...props }: ModelSelectorContentProps): React.JSX.Element;
27
- declare function ModelSelectorDialog(props: ModelSelectorDialogProps): React.JSX.Element;
28
- declare function ModelSelectorInput({ className, ...props }: ModelSelectorInputProps): React.JSX.Element;
29
- declare function ModelSelectorList(props: ModelSelectorListProps): React.JSX.Element;
30
- declare function ModelSelectorEmpty(props: ModelSelectorEmptyProps): React.JSX.Element;
31
- declare function ModelSelectorGroup(props: ModelSelectorGroupProps): React.JSX.Element;
32
- declare function ModelSelectorItem(props: ModelSelectorItemProps): React.JSX.Element;
33
- declare function ModelSelectorShortcut(props: ModelSelectorShortcutProps): React.JSX.Element;
34
- declare function ModelSelectorSeparator(props: ModelSelectorSeparatorProps): React.JSX.Element;
35
- declare function ModelSelectorLogo({ alt, className, provider, src, ...props }: ModelSelectorLogoProps): React.JSX.Element;
36
- declare function ModelSelectorLogoGroup({ className, ...props }: ModelSelectorLogoGroupProps): React.JSX.Element;
37
- declare function ModelSelectorName({ className, ...props }: ModelSelectorNameProps): React.JSX.Element;
38
- export { ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger, };
39
- export type { ModelSelectorContentProps, ModelSelectorDialogProps, ModelSelectorEmptyProps, ModelSelectorGroupProps, ModelSelectorInputProps, ModelSelectorItemProps, ModelSelectorListProps, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparatorProps, ModelSelectorShortcutProps, ModelSelectorTriggerProps, };