@elizaos/client 1.5.5-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 (209) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +350 -0
  3. package/dist/assets/empty-module-CLMscLYw.js +1 -0
  4. package/dist/assets/main-BBZ_3lkn.css +5999 -0
  5. package/dist/assets/main-C5zNUkXH.js +7 -0
  6. package/dist/assets/main-Dz64ENQg.js +614 -0
  7. package/dist/assets/react-vendor-DM5m98rr.js +545 -0
  8. package/dist/assets/ui-vendor-BQCqNqg0.js +1 -0
  9. package/dist/elizaos-avatar.png +0 -0
  10. package/dist/elizaos-icon.png +0 -0
  11. package/dist/elizaos-logo-light.png +0 -0
  12. package/dist/elizaos.webp +0 -0
  13. package/dist/favicon.ico +0 -0
  14. package/dist/images/agents/agent1.png +0 -0
  15. package/dist/images/agents/agent2.png +0 -0
  16. package/dist/images/agents/agent3.png +0 -0
  17. package/dist/images/agents/agent4.png +0 -0
  18. package/dist/images/agents/agent5.png +0 -0
  19. package/dist/index.html +14 -0
  20. package/index.html +24 -0
  21. package/package.json +159 -0
  22. package/postcss.config.js +3 -0
  23. package/public/elizaos-avatar.png +0 -0
  24. package/public/elizaos-icon.png +0 -0
  25. package/public/elizaos-logo-light.png +0 -0
  26. package/public/elizaos.webp +0 -0
  27. package/public/favicon.ico +0 -0
  28. package/public/images/agents/agent1.png +0 -0
  29. package/public/images/agents/agent2.png +0 -0
  30. package/public/images/agents/agent3.png +0 -0
  31. package/public/images/agents/agent4.png +0 -0
  32. package/public/images/agents/agent5.png +0 -0
  33. package/src/App.tsx +222 -0
  34. package/src/components/AgentDetailsPanel.tsx +147 -0
  35. package/src/components/ChatInputArea.tsx +196 -0
  36. package/src/components/ChatMessageListComponent.tsx +139 -0
  37. package/src/components/actionTool.tsx +186 -0
  38. package/src/components/add-agent-card.tsx +77 -0
  39. package/src/components/agent-action-viewer.tsx +816 -0
  40. package/src/components/agent-avatar-stack.tsx +121 -0
  41. package/src/components/agent-card.cy.tsx +259 -0
  42. package/src/components/agent-card.tsx +177 -0
  43. package/src/components/agent-creator.tsx +142 -0
  44. package/src/components/agent-log-viewer.tsx +645 -0
  45. package/src/components/agent-memory-edit-overlay.tsx +461 -0
  46. package/src/components/agent-memory-viewer.tsx +504 -0
  47. package/src/components/agent-settings.tsx +270 -0
  48. package/src/components/agent-sidebar.tsx +178 -0
  49. package/src/components/api-key-dialog.tsx +113 -0
  50. package/src/components/app-sidebar.tsx +685 -0
  51. package/src/components/array-input.tsx +116 -0
  52. package/src/components/audio-recorder.tsx +292 -0
  53. package/src/components/avatar-panel.tsx +141 -0
  54. package/src/components/character-form.tsx +1138 -0
  55. package/src/components/chat.tsx +1813 -0
  56. package/src/components/combobox.tsx +187 -0
  57. package/src/components/confirmation-dialog.tsx +59 -0
  58. package/src/components/connection-error-banner.tsx +101 -0
  59. package/src/components/connection-status.cy.tsx +73 -0
  60. package/src/components/connection-status.tsx +155 -0
  61. package/src/components/copy-button.tsx +35 -0
  62. package/src/components/delete-button.tsx +24 -0
  63. package/src/components/env-settings.tsx +261 -0
  64. package/src/components/group-card.tsx +160 -0
  65. package/src/components/group-panel.tsx +543 -0
  66. package/src/components/input-copy.tsx +21 -0
  67. package/src/components/logs-page.tsx +41 -0
  68. package/src/components/media-content.tsx +385 -0
  69. package/src/components/memory-graph.tsx +170 -0
  70. package/src/components/missing-secrets-dialog.tsx +72 -0
  71. package/src/components/onboarding-tour.tsx +247 -0
  72. package/src/components/page-title.tsx +8 -0
  73. package/src/components/plugins-panel.tsx +383 -0
  74. package/src/components/profile-card.tsx +66 -0
  75. package/src/components/profile-overlay.tsx +283 -0
  76. package/src/components/retry-button.tsx +28 -0
  77. package/src/components/secret-panel.tsx +1505 -0
  78. package/src/components/server-management.tsx +264 -0
  79. package/src/components/split-button.tsx +148 -0
  80. package/src/components/stop-agent-button.tsx +99 -0
  81. package/src/components/ui/alert-dialog.cy.tsx +333 -0
  82. package/src/components/ui/alert-dialog.tsx +115 -0
  83. package/src/components/ui/alert.tsx +49 -0
  84. package/src/components/ui/avatar.cy.tsx +180 -0
  85. package/src/components/ui/avatar.tsx +57 -0
  86. package/src/components/ui/badge.cy.tsx +146 -0
  87. package/src/components/ui/badge.tsx +43 -0
  88. package/src/components/ui/button.cy.tsx +177 -0
  89. package/src/components/ui/button.tsx +56 -0
  90. package/src/components/ui/card.cy.tsx +160 -0
  91. package/src/components/ui/card.tsx +73 -0
  92. package/src/components/ui/chat/animated-markdown.tsx +59 -0
  93. package/src/components/ui/chat/chat-bubble.tsx +178 -0
  94. package/src/components/ui/chat/chat-container.tsx +51 -0
  95. package/src/components/ui/chat/chat-input.cy.tsx +169 -0
  96. package/src/components/ui/chat/chat-input.tsx +47 -0
  97. package/src/components/ui/chat/chat-message-list.tsx +61 -0
  98. package/src/components/ui/chat/chat-tts-button.tsx +199 -0
  99. package/src/components/ui/chat/code-block.tsx +79 -0
  100. package/src/components/ui/chat/expandable-chat.tsx +131 -0
  101. package/src/components/ui/chat/hooks/useAutoScroll.ts +86 -0
  102. package/src/components/ui/chat/markdown.tsx +209 -0
  103. package/src/components/ui/chat/message-loading.tsx +48 -0
  104. package/src/components/ui/checkbox.cy.tsx +170 -0
  105. package/src/components/ui/checkbox.tsx +30 -0
  106. package/src/components/ui/collapsible.cy.tsx +283 -0
  107. package/src/components/ui/collapsible.tsx +9 -0
  108. package/src/components/ui/command.cy.tsx +313 -0
  109. package/src/components/ui/command.tsx +143 -0
  110. package/src/components/ui/dialog.cy.tsx +279 -0
  111. package/src/components/ui/dialog.tsx +104 -0
  112. package/src/components/ui/dropdown-menu.cy.tsx +273 -0
  113. package/src/components/ui/dropdown-menu.tsx +281 -0
  114. package/src/components/ui/input.cy.tsx +82 -0
  115. package/src/components/ui/input.tsx +27 -0
  116. package/src/components/ui/label.cy.tsx +157 -0
  117. package/src/components/ui/label.tsx +19 -0
  118. package/src/components/ui/resizable.tsx +42 -0
  119. package/src/components/ui/scroll-area.cy.tsx +242 -0
  120. package/src/components/ui/scroll-area.tsx +46 -0
  121. package/src/components/ui/select.cy.tsx +277 -0
  122. package/src/components/ui/select.tsx +155 -0
  123. package/src/components/ui/separator.cy.tsx +145 -0
  124. package/src/components/ui/separator.tsx +29 -0
  125. package/src/components/ui/sheet.cy.tsx +324 -0
  126. package/src/components/ui/sheet.tsx +119 -0
  127. package/src/components/ui/sidebar.tsx +734 -0
  128. package/src/components/ui/skeleton.cy.tsx +149 -0
  129. package/src/components/ui/skeleton.tsx +17 -0
  130. package/src/components/ui/split-button.cy.tsx +274 -0
  131. package/src/components/ui/split-button.tsx +112 -0
  132. package/src/components/ui/switch.tsx +28 -0
  133. package/src/components/ui/tabs.cy.tsx +271 -0
  134. package/src/components/ui/tabs.tsx +53 -0
  135. package/src/components/ui/textarea.cy.tsx +136 -0
  136. package/src/components/ui/textarea.tsx +26 -0
  137. package/src/components/ui/toast.cy.tsx +209 -0
  138. package/src/components/ui/toast.tsx +126 -0
  139. package/src/components/ui/toaster.tsx +29 -0
  140. package/src/components/ui/tooltip.cy.tsx +244 -0
  141. package/src/components/ui/tooltip.tsx +30 -0
  142. package/src/config/agent-templates.ts +349 -0
  143. package/src/config/voice-models.ts +181 -0
  144. package/src/constants.ts +23 -0
  145. package/src/context/AuthContext.tsx +44 -0
  146. package/src/context/ConnectionContext.tsx +194 -0
  147. package/src/entry.tsx +9 -0
  148. package/src/hooks/__tests__/use-agent-tab-state.test.ts +137 -0
  149. package/src/hooks/__tests__/use-agent-update.test.tsx +250 -0
  150. package/src/hooks/__tests__/use-character-convert.test.ts +102 -0
  151. package/src/hooks/__tests__/use-panel-width-state.test.ts +243 -0
  152. package/src/hooks/__tests__/use-sidebar-state.test.ts +117 -0
  153. package/src/hooks/use-agent-management.ts +130 -0
  154. package/src/hooks/use-agent-tab-state.ts +74 -0
  155. package/src/hooks/use-agent-update.ts +469 -0
  156. package/src/hooks/use-character-convert.ts +138 -0
  157. package/src/hooks/use-confirmation.ts +55 -0
  158. package/src/hooks/use-delete-agent.ts +123 -0
  159. package/src/hooks/use-dm-channels.ts +198 -0
  160. package/src/hooks/use-elevenlabs-voices.ts +83 -0
  161. package/src/hooks/use-file-upload.ts +224 -0
  162. package/src/hooks/use-mobile.tsx +19 -0
  163. package/src/hooks/use-onboarding.tsx +49 -0
  164. package/src/hooks/use-panel-width-state.ts +147 -0
  165. package/src/hooks/use-partial-update.ts +288 -0
  166. package/src/hooks/use-plugin-details.ts +462 -0
  167. package/src/hooks/use-plugins.ts +119 -0
  168. package/src/hooks/use-query-hooks.ts +1263 -0
  169. package/src/hooks/use-server-agents.ts +62 -0
  170. package/src/hooks/use-server-version.tsx +47 -0
  171. package/src/hooks/use-sidebar-state.ts +50 -0
  172. package/src/hooks/use-socket-chat.ts +264 -0
  173. package/src/hooks/use-toast.ts +260 -0
  174. package/src/hooks/use-version.tsx +64 -0
  175. package/src/index.css +146 -0
  176. package/src/lib/api-client-config.ts +53 -0
  177. package/src/lib/api-type-mappers.ts +196 -0
  178. package/src/lib/export-utils.ts +123 -0
  179. package/src/lib/logger.ts +19 -0
  180. package/src/lib/media-utils.ts +170 -0
  181. package/src/lib/pca.test.ts +17 -0
  182. package/src/lib/pca.ts +52 -0
  183. package/src/lib/socketio-manager.ts +664 -0
  184. package/src/lib/utils.ts +168 -0
  185. package/src/main.tsx +16 -0
  186. package/src/mocks/empty-module.ts +12 -0
  187. package/src/mocks/node-module.ts +57 -0
  188. package/src/polyfills.ts +37 -0
  189. package/src/routes/agent-detail.tsx +30 -0
  190. package/src/routes/agent-list.tsx +27 -0
  191. package/src/routes/agent-settings.tsx +48 -0
  192. package/src/routes/character-detail.tsx +52 -0
  193. package/src/routes/character-form.tsx +79 -0
  194. package/src/routes/character-list.tsx +38 -0
  195. package/src/routes/chat.tsx +128 -0
  196. package/src/routes/createAgent.tsx +13 -0
  197. package/src/routes/group-new.tsx +50 -0
  198. package/src/routes/group.tsx +29 -0
  199. package/src/routes/home.tsx +218 -0
  200. package/src/routes/not-found.tsx +71 -0
  201. package/src/test/setup.ts +154 -0
  202. package/src/types/crypto-browserify.d.ts +4 -0
  203. package/src/types/index.ts +13 -0
  204. package/src/types/rooms.ts +8 -0
  205. package/src/types.ts +84 -0
  206. package/src/vite-env.d.ts +40 -0
  207. package/tailwind.config.ts +90 -0
  208. package/tsconfig.json +10 -0
  209. package/vite.config.ts +102 -0
@@ -0,0 +1,281 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
5
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
6
+
7
+ import { cn } from '@/lib/utils';
8
+
9
+ type PointerDownEvent = Parameters<
10
+ NonNullable<DropdownMenuPrimitive.DropdownMenuContentProps['onPointerDown']>
11
+ >[0];
12
+ type PointerDownOutsideEvent = Parameters<
13
+ NonNullable<DropdownMenuPrimitive.DropdownMenuContentProps['onPointerDownOutside']>
14
+ >[0];
15
+
16
+ function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
17
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
18
+ }
19
+
20
+ function DropdownMenuPortal({
21
+ ...props
22
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
23
+ return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
24
+ }
25
+
26
+ function DropdownMenuTrigger({
27
+ ...props
28
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
29
+ return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
30
+ }
31
+
32
+ function DropdownMenuContent({
33
+ className,
34
+ sideOffset = 4,
35
+ onPointerDown,
36
+ onPointerDownOutside,
37
+ onCloseAutoFocus,
38
+ ...props
39
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
40
+ const isCloseFromMouse = React.useRef<boolean>(false);
41
+
42
+ const handlePointerDown = React.useCallback(
43
+ (e: PointerDownEvent) => {
44
+ isCloseFromMouse.current = true;
45
+ onPointerDown?.(e);
46
+ },
47
+ [onPointerDown]
48
+ );
49
+
50
+ const handlePointerDownOutside = React.useCallback(
51
+ (e: PointerDownOutsideEvent) => {
52
+ isCloseFromMouse.current = true;
53
+ onPointerDownOutside?.(e);
54
+ },
55
+ [onPointerDownOutside]
56
+ );
57
+
58
+ const handleCloseAutoFocus = React.useCallback(
59
+ (e: Event) => {
60
+ if (onCloseAutoFocus) {
61
+ return onCloseAutoFocus(e);
62
+ }
63
+
64
+ if (!isCloseFromMouse.current) {
65
+ return;
66
+ }
67
+
68
+ e.preventDefault();
69
+ isCloseFromMouse.current = false;
70
+ },
71
+ [onCloseAutoFocus]
72
+ );
73
+
74
+ return (
75
+ <DropdownMenuPrimitive.Portal>
76
+ <DropdownMenuPrimitive.Content
77
+ data-slot="dropdown-menu-content"
78
+ sideOffset={sideOffset}
79
+ className={cn(
80
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border p-1 shadow-lg',
81
+ className
82
+ )}
83
+ onPointerDown={handlePointerDown}
84
+ onPointerDownOutside={handlePointerDownOutside}
85
+ onCloseAutoFocus={handleCloseAutoFocus}
86
+ {...props}
87
+ />
88
+ </DropdownMenuPrimitive.Portal>
89
+ );
90
+ }
91
+
92
+ function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
93
+ return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
94
+ }
95
+
96
+ function DropdownMenuItem({
97
+ className,
98
+ inset,
99
+ variant = 'default',
100
+ ...props
101
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
102
+ inset?: boolean;
103
+ variant?: 'default' | 'destructive';
104
+ }) {
105
+ return (
106
+ <DropdownMenuPrimitive.Item
107
+ data-slot="dropdown-menu-item"
108
+ data-inset={inset}
109
+ data-variant={variant}
110
+ className={cn(
111
+ 'focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground data-[variant=destructive]:font-normal relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm font-medium outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0',
112
+ className
113
+ )}
114
+ {...props}
115
+ />
116
+ );
117
+ }
118
+
119
+ function DropdownMenuCheckboxItem({
120
+ className,
121
+ children,
122
+ checked,
123
+ ...props
124
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
125
+ return (
126
+ <DropdownMenuPrimitive.CheckboxItem
127
+ data-slot="dropdown-menu-checkbox-item"
128
+ className={cn(
129
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
130
+ className
131
+ )}
132
+ checked={checked}
133
+ {...props}
134
+ >
135
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
136
+ <DropdownMenuPrimitive.ItemIndicator>
137
+ <CheckIcon size={16} />
138
+ </DropdownMenuPrimitive.ItemIndicator>
139
+ </span>
140
+ {children}
141
+ </DropdownMenuPrimitive.CheckboxItem>
142
+ );
143
+ }
144
+
145
+ function DropdownMenuRadioGroup({
146
+ ...props
147
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
148
+ return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
149
+ }
150
+
151
+ function DropdownMenuRadioItem({
152
+ className,
153
+ children,
154
+ ...props
155
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
156
+ return (
157
+ <DropdownMenuPrimitive.RadioItem
158
+ data-slot="dropdown-menu-radio-item"
159
+ className={cn(
160
+ 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
161
+ className
162
+ )}
163
+ {...props}
164
+ >
165
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
166
+ <DropdownMenuPrimitive.ItemIndicator>
167
+ <CircleIcon className="size-2 fill-current" />
168
+ </DropdownMenuPrimitive.ItemIndicator>
169
+ </span>
170
+ {children}
171
+ </DropdownMenuPrimitive.RadioItem>
172
+ );
173
+ }
174
+
175
+ function DropdownMenuLabel({
176
+ className,
177
+ inset,
178
+ ...props
179
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
180
+ inset?: boolean;
181
+ }) {
182
+ return (
183
+ <DropdownMenuPrimitive.Label
184
+ data-slot="dropdown-menu-label"
185
+ data-inset={inset}
186
+ className={cn(
187
+ 'text-muted-foreground px-2 py-1.5 text-xs font-medium data-[inset]:pl-8',
188
+ className
189
+ )}
190
+ {...props}
191
+ />
192
+ );
193
+ }
194
+
195
+ function DropdownMenuSeparator({
196
+ className,
197
+ ...props
198
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
199
+ return (
200
+ <DropdownMenuPrimitive.Separator
201
+ data-slot="dropdown-menu-separator"
202
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
203
+ {...props}
204
+ />
205
+ );
206
+ }
207
+
208
+ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
209
+ return (
210
+ <kbd
211
+ data-slot="dropdown-menu-shortcut"
212
+ className={cn(
213
+ 'bg-background text-muted-foreground/70 ms-auto -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium',
214
+ className
215
+ )}
216
+ {...props}
217
+ />
218
+ );
219
+ }
220
+
221
+ function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
222
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
223
+ }
224
+
225
+ function DropdownMenuSubTrigger({
226
+ className,
227
+ inset,
228
+ children,
229
+ ...props
230
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
231
+ inset?: boolean;
232
+ }) {
233
+ return (
234
+ <DropdownMenuPrimitive.SubTrigger
235
+ data-slot="dropdown-menu-sub-trigger"
236
+ data-inset={inset}
237
+ className={cn(
238
+ 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8',
239
+ className
240
+ )}
241
+ {...props}
242
+ >
243
+ {children}
244
+ <ChevronRightIcon size={16} className="text-muted-foreground/80 ml-auto" />
245
+ </DropdownMenuPrimitive.SubTrigger>
246
+ );
247
+ }
248
+
249
+ function DropdownMenuSubContent({
250
+ className,
251
+ ...props
252
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
253
+ return (
254
+ <DropdownMenuPrimitive.SubContent
255
+ data-slot="dropdown-menu-sub-content"
256
+ className={cn(
257
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border p-1 shadow-lg',
258
+ className
259
+ )}
260
+ {...props}
261
+ />
262
+ );
263
+ }
264
+
265
+ export {
266
+ DropdownMenu,
267
+ DropdownMenuCheckboxItem,
268
+ DropdownMenuContent,
269
+ DropdownMenuGroup,
270
+ DropdownMenuItem,
271
+ DropdownMenuLabel,
272
+ DropdownMenuPortal,
273
+ DropdownMenuRadioGroup,
274
+ DropdownMenuRadioItem,
275
+ DropdownMenuSeparator,
276
+ DropdownMenuShortcut,
277
+ DropdownMenuSub,
278
+ DropdownMenuSubContent,
279
+ DropdownMenuSubTrigger,
280
+ DropdownMenuTrigger,
281
+ };
@@ -0,0 +1,82 @@
1
+ /// <reference types="cypress" />
2
+ /// <reference path="../../../cypress/support/types.d.ts" />
3
+
4
+ import React from 'react';
5
+ import { Input } from './input';
6
+
7
+ describe('Input Component', () => {
8
+ it('renders correctly', () => {
9
+ cy.mount(<Input placeholder="Enter text" />);
10
+
11
+ cy.get('input').should('exist');
12
+ cy.get('input').should('have.attr', 'placeholder', 'Enter text');
13
+ });
14
+
15
+ it('accepts user input', () => {
16
+ cy.mount(<Input />);
17
+
18
+ const testText = 'Hello, World!';
19
+ cy.get('input').type(testText);
20
+ cy.get('input').should('have.value', testText);
21
+ });
22
+
23
+ it('can be disabled', () => {
24
+ cy.mount(<Input disabled />);
25
+
26
+ cy.get('input').should('be.disabled');
27
+ });
28
+
29
+ it('accepts different types', () => {
30
+ const types = ['text', 'email', 'password', 'number'] as const;
31
+
32
+ types.forEach((type) => {
33
+ cy.mount(<Input type={type} />);
34
+ cy.get('input').should('have.attr', 'type', type);
35
+ });
36
+ });
37
+
38
+ it('applies custom className', () => {
39
+ cy.mount(<Input className="custom-class bg-red-500" />);
40
+
41
+ cy.get('input').should('have.class', 'custom-class');
42
+ cy.get('input').should('have.class', 'bg-red-500');
43
+ });
44
+
45
+ it('handles onChange events', () => {
46
+ const onChange = cy.stub();
47
+
48
+ cy.mount(<Input onChange={onChange} />);
49
+
50
+ cy.get('input').type('test');
51
+ cy.wrap(onChange).should('have.been.called');
52
+ });
53
+
54
+ it('forwards ref correctly', () => {
55
+ // Test that ref prop is accepted without errors
56
+ const ref = React.createRef<HTMLInputElement>();
57
+ cy.mount(<Input ref={ref} data-testid="ref-input" />);
58
+
59
+ // Verify the input is rendered
60
+ cy.get('[data-testid="ref-input"]').should('exist');
61
+ });
62
+
63
+ it('supports readonly state', () => {
64
+ cy.mount(<Input readOnly value="Read only text" />);
65
+
66
+ cy.get('input').should('have.attr', 'readonly');
67
+ cy.get('input').should('have.value', 'Read only text');
68
+ });
69
+
70
+ it('supports max length', () => {
71
+ cy.mount(<Input maxLength={10} />);
72
+
73
+ cy.get('input').type('This is a very long text');
74
+ cy.get('input').should('have.value', 'This is a ');
75
+ });
76
+
77
+ it('supports autoComplete', () => {
78
+ cy.mount(<Input autoComplete="email" />);
79
+
80
+ cy.get('input').should('have.attr', 'autocomplete', 'email');
81
+ });
82
+ });
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+
3
+ import { cn } from '@/lib/utils';
4
+
5
+ interface InputProps extends React.ComponentProps<'input'> {
6
+ 'data-testid'?: string;
7
+ }
8
+
9
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
10
+ ({ className, type, ...props }, ref) => {
11
+ return (
12
+ <input
13
+ type={type}
14
+ className={cn(
15
+ 'flex h-12 w-full rounded border border-input bg-card px-4 py-3 text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
16
+ className
17
+ )}
18
+ ref={ref}
19
+ data-testid={props['data-testid'] || 'input'}
20
+ {...props}
21
+ />
22
+ );
23
+ }
24
+ );
25
+ Input.displayName = 'Input';
26
+
27
+ export { Input };
@@ -0,0 +1,157 @@
1
+ /// <reference types="cypress" />
2
+ /// <reference path="../../../cypress/support/types.d.ts" />
3
+
4
+ import React from 'react';
5
+ import { Label } from './label';
6
+
7
+ describe('Label Component', () => {
8
+ it('renders correctly with default props', () => {
9
+ cy.mount(<Label>Email Address</Label>);
10
+
11
+ cy.get('label').should('exist');
12
+ cy.get('label').should('contain', 'Email Address');
13
+ cy.get('label').should('have.class', 'text-sm');
14
+ cy.get('label').should('have.class', 'font-normal');
15
+ });
16
+
17
+ it('associates with form controls using htmlFor', () => {
18
+ cy.mount(
19
+ <div>
20
+ <Label htmlFor="email-input">Email</Label>
21
+ <input id="email-input" type="email" />
22
+ </div>
23
+ );
24
+
25
+ cy.get('label').should('have.attr', 'for', 'email-input');
26
+ // Clicking the label should focus the input
27
+ cy.get('label').click();
28
+ cy.get('#email-input').should('have.focus');
29
+ });
30
+
31
+ it('applies custom className', () => {
32
+ cy.mount(<Label className="custom-label text-lg">Custom Label</Label>);
33
+
34
+ cy.get('label').should('have.class', 'custom-label').should('have.class', 'text-lg');
35
+ });
36
+
37
+ it('renders with required indicator', () => {
38
+ cy.mount(
39
+ <Label>
40
+ Username <span className="text-red-500">*</span>
41
+ </Label>
42
+ );
43
+
44
+ cy.get('label').should('contain', 'Username');
45
+ cy.get('label').find('.text-red-500').should('contain', '*');
46
+ });
47
+
48
+ it('works with checkbox inputs', () => {
49
+ cy.mount(
50
+ <div className="flex items-center space-x-2">
51
+ <input type="checkbox" id="terms" />
52
+ <Label htmlFor="terms">Accept terms and conditions</Label>
53
+ </div>
54
+ );
55
+
56
+ cy.get('label').click();
57
+ cy.get('#terms').should('be.checked');
58
+ });
59
+
60
+ it('works with radio inputs', () => {
61
+ cy.mount(
62
+ <div className="space-y-2">
63
+ <div className="flex items-center space-x-2">
64
+ <input type="radio" id="option1" name="options" />
65
+ <Label htmlFor="option1">Option 1</Label>
66
+ </div>
67
+ <div className="flex items-center space-x-2">
68
+ <input type="radio" id="option2" name="options" />
69
+ <Label htmlFor="option2">Option 2</Label>
70
+ </div>
71
+ </div>
72
+ );
73
+
74
+ cy.get('label').first().click();
75
+ cy.get('#option1').should('be.checked');
76
+ cy.get('#option2').should('not.be.checked');
77
+
78
+ cy.get('label').last().click();
79
+ cy.get('#option1').should('not.be.checked');
80
+ cy.get('#option2').should('be.checked');
81
+ });
82
+
83
+ it('supports disabled state styling', () => {
84
+ cy.mount(<Label className="peer-disabled:opacity-50">Disabled Label</Label>);
85
+
86
+ cy.get('label').should('have.class', 'peer-disabled:opacity-50');
87
+ });
88
+
89
+ it('renders in a form layout', () => {
90
+ cy.mount(
91
+ <form className="space-y-4">
92
+ <div className="space-y-2">
93
+ <Label htmlFor="name">Name</Label>
94
+ <input id="name" type="text" className="w-full border rounded px-2 py-1" />
95
+ </div>
96
+ <div className="space-y-2">
97
+ <Label htmlFor="email">Email</Label>
98
+ <input id="email" type="email" className="w-full border rounded px-2 py-1" />
99
+ </div>
100
+ </form>
101
+ );
102
+
103
+ cy.get('label').should('have.length', 2);
104
+ cy.get('label').first().should('contain', 'Name');
105
+ cy.get('label').last().should('contain', 'Email');
106
+ });
107
+
108
+ it('supports custom styles', () => {
109
+ cy.mount(
110
+ <Label className="text-blue-600 uppercase tracking-wide" style={{ fontSize: '14px' }}>
111
+ Styled Label
112
+ </Label>
113
+ );
114
+
115
+ cy.get('label')
116
+ .should('have.class', 'text-blue-600')
117
+ .should('have.class', 'uppercase')
118
+ .should('have.class', 'tracking-wide')
119
+ .should('have.css', 'font-size', '14px');
120
+ });
121
+
122
+ it('works with nested content', () => {
123
+ cy.mount(
124
+ <Label>
125
+ <span className="font-bold">Bold part</span> normal part
126
+ </Label>
127
+ );
128
+
129
+ cy.get('label').find('.font-bold').should('contain', 'Bold part');
130
+ cy.get('label').should('contain', 'normal part');
131
+ });
132
+
133
+ it('supports data attributes', () => {
134
+ cy.mount(
135
+ <Label data-testid="custom-label" data-field="username">
136
+ Username
137
+ </Label>
138
+ );
139
+
140
+ cy.get('[data-testid="custom-label"]')
141
+ .should('exist')
142
+ .should('have.attr', 'data-field', 'username');
143
+ });
144
+
145
+ it('maintains proper spacing in form groups', () => {
146
+ cy.mount(
147
+ <div className="space-y-1">
148
+ <Label htmlFor="field">Field Label</Label>
149
+ <input id="field" className="w-full" />
150
+ <p className="text-sm text-gray-500">Helper text</p>
151
+ </div>
152
+ );
153
+
154
+ cy.get('label').should('be.visible');
155
+ cy.get('.space-y-1').should('exist');
156
+ });
157
+ });
@@ -0,0 +1,19 @@
1
+ import * as LabelPrimitive from '@radix-ui/react-label';
2
+ import { type VariantProps, cva } from 'class-variance-authority';
3
+ import * as React from 'react';
4
+
5
+ import { cn } from '@/lib/utils';
6
+
7
+ const labelVariants = cva(
8
+ 'text-sm font-normal text-muted-foreground leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
9
+ );
10
+
11
+ const Label = React.forwardRef<
12
+ React.ElementRef<typeof LabelPrimitive.Root>,
13
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>
14
+ >(({ className, ...props }, ref) => (
15
+ <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
16
+ ));
17
+ Label.displayName = LabelPrimitive.Root.displayName;
18
+
19
+ export { Label };
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+
3
+ import { GripVertical } from 'lucide-react';
4
+ import * as ResizablePrimitive from 'react-resizable-panels';
5
+
6
+ import { cn } from '@/lib/utils';
7
+
8
+ const ResizablePanelGroup = ({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
12
+ <ResizablePrimitive.PanelGroup
13
+ className={cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className)}
14
+ {...props}
15
+ />
16
+ );
17
+
18
+ const ResizablePanel = ResizablePrimitive.Panel;
19
+
20
+ const ResizableHandle = ({
21
+ withHandle,
22
+ className,
23
+ ...props
24
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
25
+ withHandle?: boolean;
26
+ }) => (
27
+ <ResizablePrimitive.PanelResizeHandle
28
+ className={cn(
29
+ 'relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90',
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ {withHandle && (
35
+ <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
36
+ <GripVertical className="h-2.5 w-2.5" />
37
+ </div>
38
+ )}
39
+ </ResizablePrimitive.PanelResizeHandle>
40
+ );
41
+
42
+ export { ResizablePanelGroup, ResizablePanel, ResizableHandle };