@aomi-labs/widget-lib 1.0.0 → 1.1.1

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 (76) hide show
  1. package/dist/accordion.json +18 -0
  2. package/dist/alert.json +17 -0
  3. package/dist/aomi-frame.json +24 -0
  4. package/dist/assistant-thread-list.json +22 -0
  5. package/dist/assistant-thread.json +27 -0
  6. package/dist/assistant-threadlist-sidebar.json +20 -0
  7. package/dist/assistant-tool-fallback.json +20 -0
  8. package/dist/avatar.json +17 -0
  9. package/dist/badge.json +17 -0
  10. package/dist/breadcrumb.json +17 -0
  11. package/dist/button.json +18 -0
  12. package/dist/card.json +15 -0
  13. package/dist/collapsible.json +17 -0
  14. package/dist/command.json +21 -0
  15. package/dist/dialog.json +18 -0
  16. package/dist/drawer.json +17 -0
  17. package/dist/input.json +15 -0
  18. package/dist/label.json +15 -0
  19. package/dist/notification.json +20 -0
  20. package/dist/popover.json +17 -0
  21. package/dist/registry.json +429 -0
  22. package/dist/separator.json +17 -0
  23. package/dist/sheet.json +18 -0
  24. package/dist/sidebar.json +18 -0
  25. package/dist/skeleton.json +15 -0
  26. package/dist/sonner.json +17 -0
  27. package/dist/tooltip.json +17 -0
  28. package/package.json +27 -85
  29. package/src/components/aomi-frame.tsx +221 -0
  30. package/src/components/assistant-ui/attachment.tsx +235 -0
  31. package/src/components/assistant-ui/markdown-text.tsx +228 -0
  32. package/src/components/assistant-ui/thread-list.tsx +106 -0
  33. package/src/components/assistant-ui/thread.tsx +476 -0
  34. package/src/components/assistant-ui/threadlist-sidebar.tsx +66 -0
  35. package/src/components/assistant-ui/tool-fallback.tsx +48 -0
  36. package/src/components/assistant-ui/tooltip-icon-button.tsx +42 -0
  37. package/src/components/control-bar/api-key-input.tsx +122 -0
  38. package/src/components/control-bar/index.tsx +58 -0
  39. package/src/components/control-bar/model-select.tsx +120 -0
  40. package/src/components/control-bar/namespace-select.tsx +117 -0
  41. package/src/components/control-bar/wallet-connect.tsx +75 -0
  42. package/src/components/test/ThreadContextTest.tsx +204 -0
  43. package/src/components/tools/example-tool/ExampleTool.tsx +102 -0
  44. package/src/components/ui/accordion.tsx +58 -0
  45. package/src/components/ui/alert.tsx +62 -0
  46. package/src/components/ui/avatar.tsx +53 -0
  47. package/src/components/ui/badge.tsx +37 -0
  48. package/src/components/ui/breadcrumb.tsx +109 -0
  49. package/src/components/ui/button.tsx +59 -0
  50. package/src/components/ui/card.tsx +86 -0
  51. package/src/components/ui/collapsible.tsx +12 -0
  52. package/src/components/ui/command.tsx +156 -0
  53. package/src/components/ui/dialog.tsx +143 -0
  54. package/src/components/ui/drawer.tsx +118 -0
  55. package/src/components/ui/input.tsx +21 -0
  56. package/src/components/ui/label.tsx +20 -0
  57. package/src/components/ui/notification.tsx +57 -0
  58. package/src/components/ui/popover.tsx +33 -0
  59. package/src/components/ui/separator.tsx +28 -0
  60. package/src/components/ui/sheet.tsx +139 -0
  61. package/src/components/ui/sidebar.tsx +827 -0
  62. package/src/components/ui/skeleton.tsx +15 -0
  63. package/src/components/ui/sonner.tsx +29 -0
  64. package/src/components/ui/tooltip.tsx +61 -0
  65. package/src/hooks/use-mobile.ts +21 -0
  66. package/src/index.ts +26 -0
  67. package/src/registry.ts +218 -0
  68. package/{dist/styles.css → src/themes/default.css} +21 -3
  69. package/src/themes/tokens.config.ts +39 -0
  70. package/README.md +0 -41
  71. package/dist/index.cjs +0 -3780
  72. package/dist/index.cjs.map +0 -1
  73. package/dist/index.d.cts +0 -302
  74. package/dist/index.d.ts +0 -302
  75. package/dist/index.js +0 -3696
  76. package/dist/index.js.map +0 -1
@@ -0,0 +1,228 @@
1
+ "use client";
2
+
3
+ import "@assistant-ui/react-markdown/styles/dot.css";
4
+
5
+ import {
6
+ type CodeHeaderProps,
7
+ MarkdownTextPrimitive,
8
+ unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
9
+ useIsMarkdownCodeBlock,
10
+ } from "@assistant-ui/react-markdown";
11
+ import remarkGfm from "remark-gfm";
12
+ import { type FC, memo, useState } from "react";
13
+ import { CheckIcon, CopyIcon } from "lucide-react";
14
+
15
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
16
+ import { cn } from "@aomi-labs/react";
17
+
18
+ const MarkdownTextImpl = () => {
19
+ return (
20
+ <MarkdownTextPrimitive
21
+ remarkPlugins={[remarkGfm]}
22
+ className="aui-md"
23
+ components={defaultComponents}
24
+ />
25
+ );
26
+ };
27
+
28
+ export const MarkdownText = memo(MarkdownTextImpl);
29
+
30
+ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
31
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
32
+ const onCopy = () => {
33
+ if (!code || isCopied) return;
34
+ copyToClipboard(code);
35
+ };
36
+
37
+ return (
38
+ <div className="aui-code-header-root bg-muted-foreground/15 text-foreground dark:bg-muted-foreground/20 mt-4 flex items-center justify-between gap-4 rounded-t-lg px-4 py-2 text-sm font-semibold">
39
+ <span className="aui-code-header-language lowercase [&>span]:text-xs">
40
+ {language}
41
+ </span>
42
+ <TooltipIconButton tooltip="Copy" onClick={onCopy}>
43
+ {!isCopied && <CopyIcon />}
44
+ {isCopied && <CheckIcon />}
45
+ </TooltipIconButton>
46
+ </div>
47
+ );
48
+ };
49
+
50
+ const useCopyToClipboard = ({
51
+ copiedDuration = 3000,
52
+ }: {
53
+ copiedDuration?: number;
54
+ } = {}) => {
55
+ const [isCopied, setIsCopied] = useState<boolean>(false);
56
+
57
+ const copyToClipboard = (value: string) => {
58
+ if (!value) return;
59
+
60
+ navigator.clipboard.writeText(value).then(() => {
61
+ setIsCopied(true);
62
+ setTimeout(() => setIsCopied(false), copiedDuration);
63
+ });
64
+ };
65
+
66
+ return { isCopied, copyToClipboard };
67
+ };
68
+
69
+ const defaultComponents = memoizeMarkdownComponents({
70
+ h1: ({ className, ...props }) => (
71
+ <h1
72
+ className={cn(
73
+ "aui-md-h1 mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
74
+ className,
75
+ )}
76
+ {...props}
77
+ />
78
+ ),
79
+ h2: ({ className, ...props }) => (
80
+ <h2
81
+ className={cn(
82
+ "aui-md-h2 mb-4 mt-8 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
83
+ className,
84
+ )}
85
+ {...props}
86
+ />
87
+ ),
88
+ h3: ({ className, ...props }) => (
89
+ <h3
90
+ className={cn(
91
+ "aui-md-h3 mb-4 mt-6 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
92
+ className,
93
+ )}
94
+ {...props}
95
+ />
96
+ ),
97
+ h4: ({ className, ...props }) => (
98
+ <h4
99
+ className={cn(
100
+ "aui-md-h4 mb-4 mt-6 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
101
+ className,
102
+ )}
103
+ {...props}
104
+ />
105
+ ),
106
+ h5: ({ className, ...props }) => (
107
+ <h5
108
+ className={cn(
109
+ "aui-md-h5 my-4 text-lg font-semibold first:mt-0 last:mb-0",
110
+ className,
111
+ )}
112
+ {...props}
113
+ />
114
+ ),
115
+ h6: ({ className, ...props }) => (
116
+ <h6
117
+ className={cn(
118
+ "aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
119
+ className,
120
+ )}
121
+ {...props}
122
+ />
123
+ ),
124
+ p: ({ className, ...props }) => (
125
+ <p
126
+ className={cn(
127
+ "aui-md-p mb-5 mt-5 leading-7 first:mt-0 last:mb-0",
128
+ className,
129
+ )}
130
+ {...props}
131
+ />
132
+ ),
133
+ a: ({ className, ...props }) => (
134
+ <a
135
+ className={cn(
136
+ "aui-md-a text-primary font-medium underline underline-offset-4",
137
+ className,
138
+ )}
139
+ {...props}
140
+ />
141
+ ),
142
+ blockquote: ({ className, ...props }) => (
143
+ <blockquote
144
+ className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
145
+ {...props}
146
+ />
147
+ ),
148
+ ul: ({ className, ...props }) => (
149
+ <ul
150
+ className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
151
+ {...props}
152
+ />
153
+ ),
154
+ ol: ({ className, ...props }) => (
155
+ <ol
156
+ className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
157
+ {...props}
158
+ />
159
+ ),
160
+ hr: ({ className, ...props }) => (
161
+ <hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
162
+ ),
163
+ table: ({ className, ...props }) => (
164
+ <table
165
+ className={cn(
166
+ "aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
167
+ className,
168
+ )}
169
+ {...props}
170
+ />
171
+ ),
172
+ th: ({ className, ...props }) => (
173
+ <th
174
+ className={cn(
175
+ "aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [&[align=center]]:text-center [&[align=right]]:text-right",
176
+ className,
177
+ )}
178
+ {...props}
179
+ />
180
+ ),
181
+ td: ({ className, ...props }) => (
182
+ <td
183
+ className={cn(
184
+ "aui-md-td border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
185
+ className,
186
+ )}
187
+ {...props}
188
+ />
189
+ ),
190
+ tr: ({ className, ...props }) => (
191
+ <tr
192
+ className={cn(
193
+ "aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
194
+ className,
195
+ )}
196
+ {...props}
197
+ />
198
+ ),
199
+ sup: ({ className, ...props }) => (
200
+ <sup
201
+ className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
202
+ {...props}
203
+ />
204
+ ),
205
+ pre: ({ className, ...props }) => (
206
+ <pre
207
+ className={cn(
208
+ "aui-md-pre bg-accent overflow-x-auto !rounded-t-none rounded-b-lg p-6 text-[12px] text-black",
209
+ className,
210
+ )}
211
+ {...props}
212
+ />
213
+ ),
214
+ code: function Code({ className, ...props }) {
215
+ const isCodeBlock = useIsMarkdownCodeBlock();
216
+ return (
217
+ <code
218
+ className={cn(
219
+ !isCodeBlock &&
220
+ "aui-md-inline-code bg-muted rounded border text-[12px]",
221
+ className,
222
+ )}
223
+ {...props}
224
+ />
225
+ );
226
+ },
227
+ CodeHeader,
228
+ });
@@ -0,0 +1,106 @@
1
+ "use client";
2
+
3
+ import type { FC } from "react";
4
+ import {
5
+ ThreadListItemPrimitive,
6
+ ThreadListPrimitive,
7
+ useAssistantState,
8
+ } from "@assistant-ui/react";
9
+ import { PlusIcon, TrashIcon } from "lucide-react";
10
+
11
+ import { Button } from "@/components/ui/button";
12
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
13
+ import { Skeleton } from "@/components/ui/skeleton";
14
+
15
+ export const ThreadList: FC = () => {
16
+ return (
17
+ <ThreadListPrimitive.Root className="aui-root aui-thread-list-root flex list-none flex-col items-stretch gap-1 pl-2">
18
+ <ThreadListNew />
19
+ <ThreadListItems />
20
+ </ThreadListPrimitive.Root>
21
+ );
22
+ };
23
+
24
+ const ThreadListNew: FC = () => {
25
+ return (
26
+ <ThreadListPrimitive.New asChild>
27
+ <Button
28
+ className="aui-thread-list-new hover:bg-accent data-active:bg-accent flex items-center justify-start gap-2 rounded-full px-4 py-2 text-start"
29
+ variant="ghost"
30
+ >
31
+ <PlusIcon className="size-4" />
32
+ New Chat
33
+ </Button>
34
+ </ThreadListPrimitive.New>
35
+ );
36
+ };
37
+
38
+ const ThreadListItems: FC = () => {
39
+ const isLoading = useAssistantState(({ threads }) => threads.isLoading);
40
+
41
+ if (isLoading) {
42
+ return <ThreadListSkeleton />;
43
+ }
44
+
45
+ return <ThreadListPrimitive.Items components={{ ThreadListItem }} />;
46
+ };
47
+
48
+ const ThreadListSkeleton: FC = () => {
49
+ return (
50
+ <>
51
+ {Array.from({ length: 5 }, (_, i) => (
52
+ <div
53
+ key={i}
54
+ role="status"
55
+ aria-label="Loading threads"
56
+ aria-live="polite"
57
+ className="aui-thread-list-skeleton-wrapper flex items-center gap-2 rounded-md px-3 py-2"
58
+ >
59
+ <Skeleton className="aui-thread-list-skeleton h-[22px] flex-grow" />
60
+ </div>
61
+ ))}
62
+ </>
63
+ );
64
+ };
65
+
66
+ const ThreadListItem: FC = () => {
67
+ return (
68
+ <ThreadListItemPrimitive.Root className="aui-thread-list-item hover:bg-accent focus-visible:bg-accent data-active:bg-accent flex items-center gap-2 rounded-full pl-4 transition-all focus-visible:outline-none">
69
+ <ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger flex-grow py-2 text-start">
70
+ <ThreadListItemTitle />
71
+ </ThreadListItemPrimitive.Trigger>
72
+ <ThreadListItemDelete />
73
+ </ThreadListItemPrimitive.Root>
74
+ );
75
+ };
76
+
77
+ const ThreadListItemTitle: FC = () => {
78
+ return (
79
+ <span className="aui-thread-list-item-title text-sm">
80
+ <ThreadListItemPrimitive.Title fallback="New Chat" />
81
+ </span>
82
+ );
83
+ };
84
+
85
+ const ThreadListItemDelete: FC = () => {
86
+ return (
87
+ <ThreadListItemPrimitive.Delete asChild>
88
+ <TooltipIconButton
89
+ className="aui-thread-list-item-delete text-foreground hover:text-primary ml-auto mr-3 size-4 p-0"
90
+ variant="ghost"
91
+ tooltip="Delete thread"
92
+ onClick={(event) => {
93
+ const confirmed = window.confirm(
94
+ "Delete this chat? This action cannot be undone.",
95
+ );
96
+ if (!confirmed) {
97
+ event.preventDefault();
98
+ event.stopPropagation();
99
+ }
100
+ }}
101
+ >
102
+ <TrashIcon />
103
+ </TooltipIconButton>
104
+ </ThreadListItemPrimitive.Delete>
105
+ );
106
+ };