@applica-software-guru/persona-sdk 0.1.83 → 0.1.85

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 (68) hide show
  1. package/README.md +104 -0
  2. package/dist/bundle.cjs.js +18 -30
  3. package/dist/bundle.cjs.js.map +1 -1
  4. package/dist/bundle.es.js +3506 -7033
  5. package/dist/bundle.es.js.map +1 -1
  6. package/dist/bundle.iife.js +18 -30
  7. package/dist/bundle.iife.js.map +1 -1
  8. package/dist/bundle.umd.js +17 -29
  9. package/dist/bundle.umd.js.map +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/messages.d.ts +2 -0
  13. package/dist/messages.d.ts.map +1 -1
  14. package/dist/protocol/webrtc.d.ts.map +1 -1
  15. package/dist/protocol/websocket.d.ts.map +1 -1
  16. package/dist/runtime/context.d.ts +34 -0
  17. package/dist/runtime/context.d.ts.map +1 -0
  18. package/dist/runtime/handlers.d.ts +21 -0
  19. package/dist/runtime/handlers.d.ts.map +1 -0
  20. package/dist/runtime/listeners.d.ts +6 -0
  21. package/dist/runtime/listeners.d.ts.map +1 -0
  22. package/dist/runtime/protocols.d.ts +17 -0
  23. package/dist/runtime/protocols.d.ts.map +1 -0
  24. package/dist/runtime/threads.d.ts +35 -0
  25. package/dist/runtime/threads.d.ts.map +1 -0
  26. package/dist/runtime/utils.d.ts +10 -0
  27. package/dist/runtime/utils.d.ts.map +1 -0
  28. package/dist/runtime.d.ts +4 -22
  29. package/dist/runtime.d.ts.map +1 -1
  30. package/dist/storage/base.d.ts +19 -0
  31. package/dist/storage/base.d.ts.map +1 -0
  32. package/dist/storage/index.d.ts +3 -0
  33. package/dist/storage/index.d.ts.map +1 -0
  34. package/dist/storage/persona.d.ts +30 -0
  35. package/dist/storage/persona.d.ts.map +1 -0
  36. package/dist/types.d.ts +51 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/package.json +16 -10
  39. package/playground/src/chat.tsx +51 -66
  40. package/playground/src/components/assistant-ui/thread-list.tsx +45 -12
  41. package/playground/src/components/assistant-ui/thread.tsx +34 -96
  42. package/playground/src/components/assistant-ui/threadlist-sidebar.tsx +59 -0
  43. package/playground/src/components/chat/logging.tsx +53 -0
  44. package/playground/src/components/ui/input.tsx +21 -0
  45. package/playground/src/components/ui/separator.tsx +26 -0
  46. package/playground/src/components/ui/sheet.tsx +139 -0
  47. package/playground/src/components/ui/sidebar.tsx +619 -0
  48. package/playground/src/components/ui/skeleton.tsx +13 -0
  49. package/playground/src/components/ui/tooltip.tsx +0 -2
  50. package/playground/src/hooks/theme.ts +70 -0
  51. package/playground/src/hooks/use-mobile.ts +19 -0
  52. package/src/index.ts +1 -0
  53. package/src/messages.ts +98 -8
  54. package/src/protocol/webrtc.ts +1 -0
  55. package/src/protocol/websocket.ts +5 -2
  56. package/src/runtime/context.ts +88 -0
  57. package/src/runtime/handlers.ts +276 -0
  58. package/src/runtime/index.ts +6 -0
  59. package/src/runtime/listeners.ts +79 -0
  60. package/src/runtime/protocols.ts +169 -0
  61. package/src/runtime/threads.ts +120 -0
  62. package/src/runtime/utils.ts +46 -0
  63. package/src/runtime.tsx +226 -326
  64. package/src/storage/base.ts +21 -0
  65. package/src/storage/index.ts +2 -0
  66. package/src/storage/persona.ts +132 -0
  67. package/src/types.ts +64 -2
  68. package/vite.config.ts +11 -1
@@ -1,13 +1,18 @@
1
- import type { FC } from 'react';
2
- import { ThreadListItemPrimitive, ThreadListPrimitive } from '@assistant-ui/react';
3
- import { ArchiveIcon, PlusIcon } from 'lucide-react';
1
+ import type { FC } from "react";
2
+ import {
3
+ ThreadListItemPrimitive,
4
+ ThreadListPrimitive,
5
+ useAssistantState,
6
+ } from "@assistant-ui/react";
7
+ import { ArchiveIcon, PlusIcon } from "lucide-react";
4
8
 
5
- import { Button } from '@/components/ui/button';
6
- import { TooltipIconButton } from '@/components/assistant-ui/tooltip-icon-button';
9
+ import { Button } from "@/components/ui/button";
10
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
11
+ import { Skeleton } from "@/components/ui/skeleton";
7
12
 
8
13
  export const ThreadList: FC = () => {
9
14
  return (
10
- <ThreadListPrimitive.Root className="flex flex-col items-stretch gap-1.5">
15
+ <ThreadListPrimitive.Root className="aui-root aui-thread-list-root flex flex-col items-stretch gap-1.5">
11
16
  <ThreadListNew />
12
17
  <ThreadListItems />
13
18
  </ThreadListPrimitive.Root>
@@ -18,7 +23,7 @@ const ThreadListNew: FC = () => {
18
23
  return (
19
24
  <ThreadListPrimitive.New asChild>
20
25
  <Button
21
- className="data-[active]:bg-muted hover:bg-muted flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start"
26
+ className="aui-thread-list-new flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start hover:bg-muted data-active:bg-muted"
22
27
  variant="ghost"
23
28
  >
24
29
  <PlusIcon />
@@ -29,13 +34,37 @@ const ThreadListNew: FC = () => {
29
34
  };
30
35
 
31
36
  const ThreadListItems: FC = () => {
37
+ const isLoading = useAssistantState(({ threads }) => threads.isLoading);
38
+
39
+ if (isLoading) {
40
+ return <ThreadListSkeleton />;
41
+ }
42
+
32
43
  return <ThreadListPrimitive.Items components={{ ThreadListItem }} />;
33
44
  };
34
45
 
46
+ const ThreadListSkeleton: FC = () => {
47
+ return (
48
+ <>
49
+ {Array.from({ length: 5 }, (_, i) => (
50
+ <div
51
+ key={i}
52
+ role="status"
53
+ aria-label="Loading threads"
54
+ aria-live="polite"
55
+ className="aui-thread-list-skeleton-wrapper flex items-center gap-2 rounded-md px-3 py-2"
56
+ >
57
+ <Skeleton className="aui-thread-list-skeleton h-[22px] grow" />
58
+ </div>
59
+ ))}
60
+ </>
61
+ );
62
+ };
63
+
35
64
  const ThreadListItem: FC = () => {
36
65
  return (
37
- <ThreadListItemPrimitive.Root className="data-[active]:bg-muted hover:bg-muted focus-visible:bg-muted focus-visible:ring-ring flex items-center gap-2 rounded-lg transition-all focus-visible:outline-none focus-visible:ring-2">
38
- <ThreadListItemPrimitive.Trigger className="flex-grow px-3 py-2 text-start">
66
+ <ThreadListItemPrimitive.Root className="aui-thread-list-item flex items-center gap-2 rounded-lg transition-all hover:bg-muted focus-visible:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-active:bg-muted">
67
+ <ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger grow px-3 py-2 text-start">
39
68
  <ThreadListItemTitle />
40
69
  </ThreadListItemPrimitive.Trigger>
41
70
  <ThreadListItemArchive />
@@ -45,16 +74,20 @@ const ThreadListItem: FC = () => {
45
74
 
46
75
  const ThreadListItemTitle: FC = () => {
47
76
  return (
48
- <p className="text-sm">
77
+ <span className="aui-thread-list-item-title text-sm">
49
78
  <ThreadListItemPrimitive.Title fallback="New Chat" />
50
- </p>
79
+ </span>
51
80
  );
52
81
  };
53
82
 
54
83
  const ThreadListItemArchive: FC = () => {
55
84
  return (
56
85
  <ThreadListItemPrimitive.Archive asChild>
57
- <TooltipIconButton className="hover:text-primary text-foreground ml-auto mr-3 size-4 p-0" variant="ghost" tooltip="Archive thread">
86
+ <TooltipIconButton
87
+ className="aui-thread-list-item-archive mr-3 ml-auto size-4 p-0 text-foreground hover:text-primary"
88
+ variant="ghost"
89
+ tooltip="Archive thread"
90
+ >
58
91
  <ArchiveIcon />
59
92
  </TooltipIconButton>
60
93
  </ThreadListItemPrimitive.Archive>
@@ -1,44 +1,21 @@
1
- import {
2
- ArrowDownIcon,
3
- ArrowUpIcon,
4
- CheckIcon,
5
- ChevronLeftIcon,
6
- ChevronRightIcon,
7
- CopyIcon,
8
- PencilIcon,
9
- RefreshCwIcon,
10
- Square,
11
- } from "lucide-react";
1
+ import { ArrowDownIcon, ArrowUpIcon, CheckIcon, CopyIcon, RefreshCwIcon, Square } from 'lucide-react';
12
2
 
13
- import {
14
- ActionBarPrimitive,
15
- BranchPickerPrimitive,
16
- ComposerPrimitive,
17
- ErrorPrimitive,
18
- MessagePrimitive,
19
- ThreadPrimitive,
20
- } from "@assistant-ui/react";
3
+ import { ActionBarPrimitive, ComposerPrimitive, ErrorPrimitive, MessagePrimitive, ThreadPrimitive } from '@assistant-ui/react';
21
4
 
22
- import type { FC } from "react";
5
+ import type { FC } from 'react';
23
6
 
24
- import { Button } from "@/components/ui/button";
25
- import { MarkdownText } from "@/components/assistant-ui/markdown-text";
26
- import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
27
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
28
- import {
29
- ComposerAddAttachment,
30
- ComposerAttachments,
31
- UserMessageAttachments,
32
- } from "@/components/assistant-ui/attachment";
33
-
34
- import { cn } from "@/lib/utils";
7
+ import { Button } from '@/components/ui/button';
8
+ import { MarkdownText } from '@/components/assistant-ui/markdown-text';
9
+ import { ToolFallback } from '@/components/assistant-ui/tool-fallback';
10
+ import { TooltipIconButton } from '@/components/assistant-ui/tooltip-icon-button';
11
+ import { ComposerAddAttachment, ComposerAttachments, UserMessageAttachments } from '@/components/assistant-ui/attachment';
35
12
 
36
13
  export const Thread: FC = () => {
37
14
  return (
38
15
  <ThreadPrimitive.Root
39
16
  className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
40
17
  style={{
41
- ["--thread-max-width" as string]: "44rem",
18
+ ['--thread-max-width' as string]: '44rem',
42
19
  }}
43
20
  >
44
21
  <ThreadPrimitive.Viewport
@@ -104,23 +81,23 @@ const ThreadSuggestions: FC = () => {
104
81
  {[
105
82
  {
106
83
  title: "What's the weather",
107
- label: "in San Francisco?",
84
+ label: 'in San Francisco?',
108
85
  action: "What's the weather in San Francisco?",
109
86
  },
110
87
  {
111
- title: "Explain React hooks",
112
- label: "like useState and useEffect",
113
- action: "Explain React hooks like useState and useEffect",
88
+ title: 'Explain React hooks',
89
+ label: 'like useState and useEffect',
90
+ action: 'Explain React hooks like useState and useEffect',
114
91
  },
115
92
  {
116
- title: "Write a SQL query",
117
- label: "to find top customers",
118
- action: "Write a SQL query to find top customers",
93
+ title: 'Write a SQL query',
94
+ label: 'to find top customers',
95
+ action: 'Write a SQL query to find top customers',
119
96
  },
120
97
  {
121
- title: "Create a meal plan",
122
- label: "for healthy weight loss",
123
- action: "Create a meal plan for healthy weight loss",
98
+ title: 'Create a meal plan',
99
+ label: 'for healthy weight loss',
100
+ action: 'Create a meal plan for healthy weight loss',
124
101
  },
125
102
  ].map((suggestedAction, index) => (
126
103
  <div
@@ -128,22 +105,14 @@ const ThreadSuggestions: FC = () => {
128
105
  className="aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-4 @md:nth-[n+3]:block nth-[n+3]:hidden animate-in fill-mode-both duration-300 ease-out"
129
106
  style={{ animationDelay: `${index * 50}ms` }}
130
107
  >
131
- <ThreadPrimitive.Suggestion
132
- prompt={suggestedAction.action}
133
- send
134
- asChild
135
- >
108
+ <ThreadPrimitive.Suggestion prompt={suggestedAction.action} send asChild>
136
109
  <Button
137
110
  variant="ghost"
138
111
  className="aui-thread-welcome-suggestion h-auto w-full flex-1 @md:flex-col flex-wrap items-start justify-start gap-1 rounded-3xl border px-5 py-4 text-left text-sm dark:hover:bg-accent/60"
139
112
  aria-label={suggestedAction.action}
140
113
  >
141
- <span className="aui-thread-welcome-suggestion-text-1 font-medium">
142
- {suggestedAction.title}
143
- </span>
144
- <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
145
- {suggestedAction.label}
146
- </span>
114
+ <span className="aui-thread-welcome-suggestion-text-1 font-medium">{suggestedAction.title}</span>
115
+ <span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">{suggestedAction.label}</span>
147
116
  </Button>
148
117
  </ThreadPrimitive.Suggestion>
149
118
  </div>
@@ -218,6 +187,15 @@ const MessageError: FC = () => {
218
187
  );
219
188
  };
220
189
 
190
+ const ReasoningContent: FC<{ text: string }> = ({ text }) => {
191
+ return (
192
+ <div className="aui-reasoning-content my-2 rounded-lg border border-muted bg-muted/30 p-3 text-muted-foreground text-sm italic">
193
+ <div className="mb-1 font-semibold text-xs uppercase tracking-wide">Thinking...</div>
194
+ <div>{text}</div>
195
+ </div>
196
+ );
197
+ };
198
+
221
199
  const AssistantMessage: FC = () => {
222
200
  return (
223
201
  <MessagePrimitive.Root
@@ -228,6 +206,7 @@ const AssistantMessage: FC = () => {
228
206
  <MessagePrimitive.Parts
229
207
  components={{
230
208
  Text: MarkdownText,
209
+ Reasoning: ReasoningContent,
231
210
  tools: { Fallback: ToolFallback },
232
211
  }}
233
212
  />
@@ -235,7 +214,6 @@ const AssistantMessage: FC = () => {
235
214
  </div>
236
215
 
237
216
  <div className="aui-assistant-message-footer mt-2 ml-2 flex">
238
- <BranchPicker />
239
217
  <AssistantActionBar />
240
218
  </div>
241
219
  </MessagePrimitive.Root>
@@ -285,24 +263,14 @@ const UserMessage: FC = () => {
285
263
  <UserActionBar />
286
264
  </div>
287
265
  </div>
288
-
289
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
290
266
  </MessagePrimitive.Root>
291
267
  );
292
268
  };
293
269
 
294
270
  const UserActionBar: FC = () => {
295
271
  return (
296
- <ActionBarPrimitive.Root
297
- hideWhenRunning
298
- autohide="not-last"
299
- className="aui-user-action-bar-root flex flex-col items-end"
300
- >
301
- <ActionBarPrimitive.Edit asChild>
302
- <TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
303
- <PencilIcon />
304
- </TooltipIconButton>
305
- </ActionBarPrimitive.Edit>
272
+ <ActionBarPrimitive.Root hideWhenRunning autohide="not-last" className="aui-user-action-bar-root flex flex-col items-end">
273
+ {/* Edit button disabled */}
306
274
  </ActionBarPrimitive.Root>
307
275
  );
308
276
  };
@@ -332,33 +300,3 @@ const EditComposer: FC = () => {
332
300
  </MessagePrimitive.Root>
333
301
  );
334
302
  };
335
-
336
- const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
337
- className,
338
- ...rest
339
- }) => {
340
- return (
341
- <BranchPickerPrimitive.Root
342
- hideWhenSingleBranch
343
- className={cn(
344
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
345
- className,
346
- )}
347
- {...rest}
348
- >
349
- <BranchPickerPrimitive.Previous asChild>
350
- <TooltipIconButton tooltip="Previous">
351
- <ChevronLeftIcon />
352
- </TooltipIconButton>
353
- </BranchPickerPrimitive.Previous>
354
- <span className="aui-branch-picker-state font-medium">
355
- <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
356
- </span>
357
- <BranchPickerPrimitive.Next asChild>
358
- <TooltipIconButton tooltip="Next">
359
- <ChevronRightIcon />
360
- </TooltipIconButton>
361
- </BranchPickerPrimitive.Next>
362
- </BranchPickerPrimitive.Root>
363
- );
364
- };
@@ -0,0 +1,59 @@
1
+ import * as React from 'react';
2
+ import { Github, MessagesSquare } from 'lucide-react';
3
+ import {
4
+ Sidebar,
5
+ SidebarContent,
6
+ SidebarFooter,
7
+ SidebarHeader,
8
+ SidebarMenu,
9
+ SidebarMenuButton,
10
+ SidebarMenuItem,
11
+ SidebarRail,
12
+ } from '@/components/ui/sidebar';
13
+ import { ThreadList } from '@/components/assistant-ui/thread-list';
14
+
15
+ export function ThreadListSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
16
+ return (
17
+ <Sidebar {...props}>
18
+ <SidebarHeader className="aui-sidebar-header mb-2 border-b">
19
+ <div className="aui-sidebar-header-content flex items-center justify-between">
20
+ <SidebarMenu>
21
+ <SidebarMenuItem>
22
+ <SidebarMenuButton size="lg" asChild>
23
+ <a href="https://assistant-ui.com" target="_blank" rel="noopener noreferrer">
24
+ <div className="aui-sidebar-header-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
25
+ <MessagesSquare className="aui-sidebar-header-icon size-4" />
26
+ </div>
27
+ <div className="aui-sidebar-header-heading mr-6 flex flex-col gap-0.5 leading-none">
28
+ <span className="aui-sidebar-header-title font-semibold">assistant-ui</span>
29
+ </div>
30
+ </a>
31
+ </SidebarMenuButton>
32
+ </SidebarMenuItem>
33
+ </SidebarMenu>
34
+ </div>
35
+ </SidebarHeader>
36
+ <SidebarContent className="aui-sidebar-content px-2">
37
+ <ThreadList />
38
+ </SidebarContent>
39
+ <SidebarRail />
40
+ <SidebarFooter className="aui-sidebar-footer border-t">
41
+ <SidebarMenu>
42
+ <SidebarMenuItem>
43
+ <SidebarMenuButton size="lg" asChild>
44
+ <a href="https://github.com/assistant-ui/assistant-ui" target="_blank">
45
+ <div className="aui-sidebar-footer-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
46
+ <Github className="aui-sidebar-footer-icon size-4" />
47
+ </div>
48
+ <div className="aui-sidebar-footer-heading flex flex-col gap-0.5 leading-none">
49
+ <span className="aui-sidebar-footer-title font-semibold">GitHub</span>
50
+ <span>View Source</span>
51
+ </div>
52
+ </a>
53
+ </SidebarMenuButton>
54
+ </SidebarMenuItem>
55
+ </SidebarMenu>
56
+ </SidebarFooter>
57
+ </Sidebar>
58
+ );
59
+ }
@@ -0,0 +1,53 @@
1
+ import { usePersonaRuntimeEndpoint, usePersonaRuntimeMessages } from '@applica-software-guru/persona-sdk';
2
+ import { useMemo } from 'react';
3
+ import _ from 'lodash';
4
+
5
+ function MessageLogger() {
6
+ const messages = usePersonaRuntimeMessages();
7
+ const { reasoning, user, assistant, sources } = useMemo(() => {
8
+ const reasoning = _.filter(messages, (message) => message.role === 'assistant' && message.type === 'reasoning').length;
9
+ const user = _.filter(messages, (message) => message.role === 'user').length;
10
+ const assistant = _.filter(messages, (message) => message.role === 'assistant').length;
11
+ const sources = _.filter(messages, (message) => message.role === 'assistant' && message.sources).length;
12
+ return { reasoning, user, assistant, sources };
13
+ }, [messages]);
14
+ return (
15
+ <div className="absolute top-0 left-0 w-30 h-40 overflow-y-auto m-2 box-border border-gray-300 rounded-lg shadow-lg p-2">
16
+ <h3 className="text-md font-bold mb-2">Messages</h3>
17
+ <p className="top-0 left-0 bg-white text-black text-sm">
18
+ <span className="text-gray-500">
19
+ User: <span className="font-bold">{user}</span>
20
+ </span>
21
+ <br />
22
+ <span className="text-gray-500">
23
+ Assistant: <span className="font-bold">{assistant}</span>
24
+ </span>
25
+ <br />
26
+ <span className="text-gray-500">
27
+ Reasoning: <span className="font-bold">{reasoning}</span>
28
+ </span>
29
+ <br />
30
+ <span className="text-gray-500">
31
+ Sources: <span className="font-bold">{sources}</span>
32
+ </span>
33
+ <br />
34
+ <span className="text-gray-500">
35
+ Total: <span className="font-bold">{messages.length}</span>
36
+ </span>
37
+ <br />
38
+ </p>
39
+ </div>
40
+ );
41
+ }
42
+
43
+ function EndpointLogger() {
44
+ const endpoint = usePersonaRuntimeEndpoint();
45
+ return (
46
+ <div className="absolute top-0 right-0 w-50 h-40 overflow-y-auto m-2 box-border border-gray-300 rounded-lg shadow-lg p-2">
47
+ <h3 className="text-md font-bold mb-2">Endpoint</h3>
48
+ <p className="top-0 left-0 bg-white text-black text-sm">{endpoint || 'No endpoint available'}</p>
49
+ </div>
50
+ );
51
+ }
52
+
53
+ export { MessageLogger, EndpointLogger };
@@ -0,0 +1,21 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Input }
@@ -0,0 +1,26 @@
1
+ import * as React from "react"
2
+ import * as SeparatorPrimitive from "@radix-ui/react-separator"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ function Separator({
7
+ className,
8
+ orientation = "horizontal",
9
+ decorative = true,
10
+ ...props
11
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
12
+ return (
13
+ <SeparatorPrimitive.Root
14
+ data-slot="separator"
15
+ decorative={decorative}
16
+ orientation={orientation}
17
+ className={cn(
18
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
19
+ className
20
+ )}
21
+ {...props}
22
+ />
23
+ )
24
+ }
25
+
26
+ export { Separator }
@@ -0,0 +1,139 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SheetPrimitive from "@radix-ui/react-dialog"
5
+ import { XIcon } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
10
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
11
+ }
12
+
13
+ function SheetTrigger({
14
+ ...props
15
+ }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
16
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
17
+ }
18
+
19
+ function SheetClose({
20
+ ...props
21
+ }: React.ComponentProps<typeof SheetPrimitive.Close>) {
22
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
23
+ }
24
+
25
+ function SheetPortal({
26
+ ...props
27
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
28
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
29
+ }
30
+
31
+ function SheetOverlay({
32
+ className,
33
+ ...props
34
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
35
+ return (
36
+ <SheetPrimitive.Overlay
37
+ data-slot="sheet-overlay"
38
+ className={cn(
39
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ )
45
+ }
46
+
47
+ function SheetContent({
48
+ className,
49
+ children,
50
+ side = "right",
51
+ ...props
52
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
53
+ side?: "top" | "right" | "bottom" | "left"
54
+ }) {
55
+ return (
56
+ <SheetPortal>
57
+ <SheetOverlay />
58
+ <SheetPrimitive.Content
59
+ data-slot="sheet-content"
60
+ className={cn(
61
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
62
+ side === "right" &&
63
+ "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
64
+ side === "left" &&
65
+ "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
66
+ side === "top" &&
67
+ "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
68
+ side === "bottom" &&
69
+ "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
70
+ className
71
+ )}
72
+ {...props}
73
+ >
74
+ {children}
75
+ <SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
76
+ <XIcon className="size-4" />
77
+ <span className="sr-only">Close</span>
78
+ </SheetPrimitive.Close>
79
+ </SheetPrimitive.Content>
80
+ </SheetPortal>
81
+ )
82
+ }
83
+
84
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="sheet-header"
88
+ className={cn("flex flex-col gap-1.5 p-4", className)}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
95
+ return (
96
+ <div
97
+ data-slot="sheet-footer"
98
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
99
+ {...props}
100
+ />
101
+ )
102
+ }
103
+
104
+ function SheetTitle({
105
+ className,
106
+ ...props
107
+ }: React.ComponentProps<typeof SheetPrimitive.Title>) {
108
+ return (
109
+ <SheetPrimitive.Title
110
+ data-slot="sheet-title"
111
+ className={cn("text-foreground font-semibold", className)}
112
+ {...props}
113
+ />
114
+ )
115
+ }
116
+
117
+ function SheetDescription({
118
+ className,
119
+ ...props
120
+ }: React.ComponentProps<typeof SheetPrimitive.Description>) {
121
+ return (
122
+ <SheetPrimitive.Description
123
+ data-slot="sheet-description"
124
+ className={cn("text-muted-foreground text-sm", className)}
125
+ {...props}
126
+ />
127
+ )
128
+ }
129
+
130
+ export {
131
+ Sheet,
132
+ SheetTrigger,
133
+ SheetClose,
134
+ SheetContent,
135
+ SheetHeader,
136
+ SheetFooter,
137
+ SheetTitle,
138
+ SheetDescription,
139
+ }