@rolder/kit 3.0.0-alpha.9 → 3.0.0-alpha.91

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 (217) hide show
  1. package/dist/ai/index.d.ts +2 -0
  2. package/dist/ai/index.js +2 -0
  3. package/dist/ai/ui/chat/Root.d.ts +55 -0
  4. package/dist/ai/ui/chat/Root.js +18 -0
  5. package/dist/ai/ui/chat/chatInput/File.js +71 -0
  6. package/dist/ai/ui/chat/chatInput/FileIcon.js +43 -0
  7. package/dist/ai/ui/chat/chatInput/Root.d.ts +9 -0
  8. package/dist/ai/ui/chat/chatInput/Root.js +24 -0
  9. package/dist/ai/ui/chat/chatInput/Submit.js +23 -0
  10. package/dist/ai/ui/{promptInput → chat/chatInput}/Textarea.js +8 -7
  11. package/dist/ai/ui/{promptInput → chat/chatInput}/index.d.ts +2 -3
  12. package/dist/ai/ui/{promptInput → chat/chatInput}/index.js +2 -2
  13. package/dist/ai/ui/chat/chatInput/store/file.d.ts +8 -0
  14. package/dist/ai/ui/chat/chatInput/store/file.js +32 -0
  15. package/dist/ai/ui/chat/chatInput/store/fileErrorNotificaton.d.ts +2 -0
  16. package/dist/ai/ui/chat/chatInput/store/fileErrorNotificaton.js +21 -0
  17. package/dist/ai/ui/chat/chatInput/store/index.d.ts +2 -0
  18. package/dist/ai/ui/chat/chatInput/store/index.js +2 -0
  19. package/dist/ai/ui/chat/chatInput/store/input.d.ts +13 -0
  20. package/dist/ai/ui/chat/chatInput/store/input.js +81 -0
  21. package/dist/ai/ui/chat/chatInput/store/parseFile.d.ts +2 -0
  22. package/dist/ai/ui/chat/chatInput/store/parseFile.js +23 -0
  23. package/dist/ai/ui/chat/index.d.ts +12 -0
  24. package/dist/ai/ui/chat/index.js +15 -0
  25. package/dist/ai/ui/chat/messages/Empty.d.ts +4 -0
  26. package/dist/ai/ui/chat/messages/Empty.js +11 -0
  27. package/dist/ai/ui/chat/messages/Loader.d.ts +5 -0
  28. package/dist/ai/ui/chat/messages/Loader.js +12 -0
  29. package/dist/ai/ui/chat/messages/Message.d.ts +8 -0
  30. package/dist/ai/ui/chat/messages/Message.js +22 -0
  31. package/dist/ai/ui/chat/messages/Messages.d.ts +3 -0
  32. package/dist/ai/ui/chat/messages/Messages.js +40 -0
  33. package/dist/ai/ui/chat/messages/index.d.ts +2 -0
  34. package/dist/ai/ui/chat/messages/index.js +2 -0
  35. package/dist/ai/ui/chat/parts/File.d.ts +6 -0
  36. package/dist/ai/ui/{conversation → chat/parts}/File.js +10 -10
  37. package/dist/ai/ui/chat/parts/FileIcon.js +43 -0
  38. package/dist/ai/ui/chat/parts/PartPaper.d.ts +8 -0
  39. package/dist/ai/ui/chat/parts/PartPaper.js +14 -0
  40. package/dist/ai/ui/chat/parts/TextPart.d.ts +6 -0
  41. package/dist/ai/ui/chat/parts/TextPart.js +15 -0
  42. package/dist/ai/ui/chat/parts/ToolExecution.d.ts +7 -0
  43. package/dist/ai/ui/chat/parts/ToolExecution.js +56 -0
  44. package/dist/ai/ui/chat/parts/ToolPart.d.ts +10 -0
  45. package/dist/ai/ui/chat/parts/ToolPart.js +24 -0
  46. package/dist/ai/ui/chat/parts/index.d.ts +3 -0
  47. package/dist/ai/ui/chat/parts/index.js +3 -0
  48. package/dist/ai/ui/chat/store/index.d.ts +4 -0
  49. package/dist/ai/ui/chat/store/index.js +4 -0
  50. package/dist/ai/ui/chat/store/messages.d.ts +12 -0
  51. package/dist/ai/ui/chat/store/messages.js +40 -0
  52. package/dist/ai/ui/chat/store/send.d.ts +14 -0
  53. package/dist/ai/ui/chat/store/send.js +16 -0
  54. package/dist/ai/ui/chat/store/states.d.ts +11 -0
  55. package/dist/ai/ui/chat/store/states.js +20 -0
  56. package/dist/ai/ui/chat/store/useInitChat.d.ts +3 -0
  57. package/dist/ai/ui/chat/store/useInitChat.js +40 -0
  58. package/dist/ai/ui/index.d.ts +1 -0
  59. package/dist/ai/ui/index.js +1 -0
  60. package/dist/ai/utils/index.d.ts +2 -0
  61. package/dist/ai/utils/index.js +2 -0
  62. package/dist/app/AppDefaults.js +1 -1
  63. package/dist/app/DefaultApp.js +1 -1
  64. package/dist/app/cookieColorSchemeManager.js +1 -1
  65. package/dist/app/defaultRequestMiddlewares.d.ts +1 -1
  66. package/dist/app/defaultTheme.d.ts +6 -6
  67. package/dist/app/index.d.ts +4 -0
  68. package/dist/app/index.js +4 -0
  69. package/dist/hooks/index.d.ts +2 -0
  70. package/dist/hooks/index.js +2 -0
  71. package/dist/index.d.ts +5 -26
  72. package/dist/index.js +5 -26
  73. package/dist/styles.css +3 -8
  74. package/dist/tanstackFunctions/cookie/index.d.ts +3 -0
  75. package/dist/tanstackFunctions/cookie/index.js +4 -0
  76. package/dist/{functions → tanstackFunctions/cookie}/setCookie.d.ts +1 -1
  77. package/dist/tanstackFunctions/index.d.ts +3 -0
  78. package/dist/tanstackFunctions/index.js +3 -0
  79. package/dist/tanstackFunctions/s3/getS3Client.d.ts +2 -0
  80. package/dist/tanstackFunctions/s3/getS3Client.js +18 -0
  81. package/dist/tanstackFunctions/s3/getSignedFileUrlFn.d.ts +4 -0
  82. package/dist/tanstackFunctions/s3/getSignedFileUrlFn.js +21 -0
  83. package/dist/tanstackFunctions/s3/index.d.ts +2 -0
  84. package/dist/tanstackFunctions/s3/index.js +2 -0
  85. package/dist/tanstackFunctions/s3/uploadRequest.d.ts +3 -0
  86. package/dist/tanstackFunctions/s3/uploadRequest.js +21 -0
  87. package/dist/{surreal → tanstackFunctions/surreal}/connection.js +5 -1
  88. package/dist/tanstackFunctions/surreal/deafaultCrud.d.ts +2 -0
  89. package/dist/tanstackFunctions/surreal/index.d.ts +4 -0
  90. package/dist/tanstackFunctions/surreal/index.js +4 -0
  91. package/dist/ui/AnimatedChevron.d.ts +3 -4
  92. package/dist/ui/AnimatedChevron.js +6 -25
  93. package/dist/ui/JsonInput.d.ts +1 -1
  94. package/dist/ui/JsonInput.js +1 -1
  95. package/dist/ui/editor/Content.d.ts +2 -2
  96. package/dist/ui/editor/Content.js +2 -2
  97. package/dist/ui/editor/Root.d.ts +7 -1
  98. package/dist/ui/editor/Root.js +42 -5
  99. package/dist/ui/editor/Toolbar.d.ts +3 -2
  100. package/dist/ui/editor/Toolbar.js +7 -25
  101. package/dist/ui/editor/index.d.ts +5 -9
  102. package/dist/ui/editor/index.js +3 -4
  103. package/dist/ui/editor/store.d.ts +6 -0
  104. package/dist/ui/editor/store.js +10 -0
  105. package/dist/ui/error/DefaultError.d.ts +1 -1
  106. package/dist/ui/error/DefaultNotFound.d.ts +1 -1
  107. package/dist/ui/error/Forbidden.d.ts +1 -1
  108. package/dist/ui/form/buttons/CancelButton.d.ts +2 -2
  109. package/dist/ui/form/buttons/CancelButton.js +4 -26
  110. package/dist/ui/form/buttons/SubmitButton.d.ts +2 -2
  111. package/dist/ui/form/buttons/SubmitButton.js +4 -29
  112. package/dist/ui/form/buttons/SubscribeActionIcon.d.ts +2 -2
  113. package/dist/ui/form/buttons/SubscribeButton.d.ts +2 -2
  114. package/dist/ui/form/context.d.ts +55 -55
  115. package/dist/ui/form/context.js +3 -3
  116. package/dist/ui/form/fields/JsonField.d.ts +1 -1
  117. package/dist/ui/form/fields/MultiSelectField.d.ts +1 -1
  118. package/dist/ui/form/fields/NumberField.d.ts +1 -1
  119. package/dist/ui/form/fields/PasswordField.d.ts +2 -0
  120. package/dist/ui/form/fields/{PassowrdField.js → PasswordField.js} +2 -2
  121. package/dist/ui/form/fields/SelectField.d.ts +1 -1
  122. package/dist/ui/form/fields/SwitchField.d.ts +1 -1
  123. package/dist/ui/form/fields/TextField.d.ts +1 -1
  124. package/dist/ui/form/fields/TextPasswordField.d.ts +2 -0
  125. package/dist/ui/form/fields/TextPasswordField.js +29 -0
  126. package/dist/ui/form/fields/TextareaField.d.ts +1 -1
  127. package/dist/ui/form/fields/index.d.ts +2 -2
  128. package/dist/ui/form/fields/index.js +2 -2
  129. package/dist/ui/index.d.ts +9 -0
  130. package/dist/ui/index.js +9 -0
  131. package/dist/ui/saveInput/JsonInput.d.ts +2 -2
  132. package/dist/ui/saveInput/NumberInput.d.ts +2 -2
  133. package/dist/ui/saveInput/SaveInput.d.ts +14 -14
  134. package/dist/ui/saveInput/Select.d.ts +2 -2
  135. package/dist/ui/saveInput/Switch.d.ts +2 -2
  136. package/dist/ui/saveInput/TextInput.d.ts +2 -2
  137. package/dist/ui/saveInput/Textarea.d.ts +2 -2
  138. package/dist/ui/scrollArea/Root.d.ts +7 -0
  139. package/dist/ui/scrollArea/Root.js +42 -0
  140. package/dist/ui/scrollArea/ScrollButton.d.ts +7 -0
  141. package/dist/ui/scrollArea/ScrollButton.js +30 -0
  142. package/dist/ui/scrollArea/index.d.ts +6 -3
  143. package/dist/ui/scrollArea/index.js +7 -3
  144. package/dist/ui/scrollArea/methods.d.ts +4 -0
  145. package/dist/ui/scrollArea/methods.js +32 -0
  146. package/dist/ui/scrollArea/store.d.ts +12 -0
  147. package/dist/ui/scrollArea/store.js +25 -0
  148. package/package.json +73 -68
  149. package/dist/ai/ui/conversation/ConversationContext.d.ts +0 -7
  150. package/dist/ai/ui/conversation/ConversationContext.js +0 -8
  151. package/dist/ai/ui/conversation/ConversationProvider.d.ts +0 -2
  152. package/dist/ai/ui/conversation/ConversationProvider.js +0 -14
  153. package/dist/ai/ui/conversation/Empty.d.ts +0 -1
  154. package/dist/ai/ui/conversation/Empty.js +0 -21
  155. package/dist/ai/ui/conversation/File.d.ts +0 -4
  156. package/dist/ai/ui/conversation/FileIcon.js +0 -225
  157. package/dist/ai/ui/conversation/Loader.d.ts +0 -2
  158. package/dist/ai/ui/conversation/Loader.js +0 -12
  159. package/dist/ai/ui/conversation/Message.d.ts +0 -4
  160. package/dist/ai/ui/conversation/Message.js +0 -25
  161. package/dist/ai/ui/conversation/Root.d.ts +0 -2
  162. package/dist/ai/ui/conversation/Root.js +0 -26
  163. package/dist/ai/ui/conversation/index.d.ts +0 -13
  164. package/dist/ai/ui/conversation/index.js +0 -14
  165. package/dist/ai/ui/conversation/types.d.ts +0 -7
  166. package/dist/ai/ui/conversation/types.js +0 -0
  167. package/dist/ai/ui/conversation/useChatMessage.d.ts +0 -2
  168. package/dist/ai/ui/conversation/useChatMessage.js +0 -12
  169. package/dist/ai/ui/promptInput/File.js +0 -117
  170. package/dist/ai/ui/promptInput/FileIcon.js +0 -225
  171. package/dist/ai/ui/promptInput/PromptInputContext.d.ts +0 -12
  172. package/dist/ai/ui/promptInput/PromptInputContext.js +0 -8
  173. package/dist/ai/ui/promptInput/PromptInputProvider.d.ts +0 -2
  174. package/dist/ai/ui/promptInput/PromptInputProvider.js +0 -50
  175. package/dist/ai/ui/promptInput/Root.d.ts +0 -3
  176. package/dist/ai/ui/promptInput/Root.js +0 -17
  177. package/dist/ai/ui/promptInput/Submit.js +0 -40
  178. package/dist/ai/ui/promptInput/types.d.ts +0 -11
  179. package/dist/ai/ui/promptInput/types.js +0 -0
  180. package/dist/surreal/deafaultCrud.d.ts +0 -2
  181. package/dist/ui/editor/Provider.d.ts +0 -17
  182. package/dist/ui/editor/Provider.js +0 -80
  183. package/dist/ui/editor/types.d.ts +0 -7
  184. package/dist/ui/editor/types.js +0 -0
  185. package/dist/ui/form/fields/PassowrdField.d.ts +0 -2
  186. package/dist/ui/form/fields/TextPassowrdField.d.ts +0 -2
  187. package/dist/ui/form/fields/TextPassowrdField.js +0 -51
  188. package/dist/ui/scrollArea/ScrollArea.d.ts +0 -62
  189. package/dist/ui/scrollArea/ScrollArea.js +0 -30
  190. package/dist/ui/scrollArea/ScrollAreaButton.d.ts +0 -5
  191. package/dist/ui/scrollArea/ScrollAreaButton.js +0 -51
  192. package/dist/ui/scrollArea/ScrollAreaContent.d.ts +0 -6
  193. package/dist/ui/scrollArea/ScrollAreaContent.js +0 -29
  194. package/dist/ui/scrollArea/context.d.ts +0 -28
  195. package/dist/ui/scrollArea/context.js +0 -10
  196. package/dist/ui/scrollArea/types.d.ts +0 -65
  197. package/dist/ui/scrollArea/types.js +0 -0
  198. package/dist/ui/scrollArea/useScrollArea.d.ts +0 -9
  199. package/dist/ui/scrollArea/useScrollArea.js +0 -146
  200. /package/dist/ai/ui/{promptInput → chat/chatInput}/File.d.ts +0 -0
  201. /package/dist/ai/ui/{conversation → chat/chatInput}/FileIcon.d.ts +0 -0
  202. /package/dist/ai/ui/{promptInput → chat/chatInput}/Footer.d.ts +0 -0
  203. /package/dist/ai/ui/{promptInput → chat/chatInput}/Footer.js +0 -0
  204. /package/dist/ai/ui/{promptInput → chat/chatInput}/Submit.d.ts +0 -0
  205. /package/dist/ai/ui/{promptInput → chat/chatInput}/Textarea.d.ts +0 -0
  206. /package/dist/ai/ui/{promptInput → chat/parts}/FileIcon.d.ts +0 -0
  207. /package/dist/{functions → tanstackFunctions/cookie}/getCookie.d.ts +0 -0
  208. /package/dist/{functions → tanstackFunctions/cookie}/getCookie.js +0 -0
  209. /package/dist/{functions → tanstackFunctions/cookie}/setCookie.js +0 -0
  210. /package/dist/{functions → tanstackFunctions/cookie}/setCookies.d.ts +0 -0
  211. /package/dist/{functions → tanstackFunctions/cookie}/setCookies.js +0 -0
  212. /package/dist/{surreal → tanstackFunctions/surreal}/connection.d.ts +0 -0
  213. /package/dist/{surreal → tanstackFunctions/surreal}/deafaultCrud.js +0 -0
  214. /package/dist/{surreal → tanstackFunctions/surreal}/deserialize.d.ts +0 -0
  215. /package/dist/{surreal → tanstackFunctions/surreal}/deserialize.js +0 -0
  216. /package/dist/{surreal → tanstackFunctions/surreal}/encryption.d.ts +0 -0
  217. /package/dist/{surreal → tanstackFunctions/surreal}/encryption.js +0 -0
@@ -0,0 +1,2 @@
1
+ export * from './ui';
2
+ export * from './utils';
@@ -0,0 +1,2 @@
1
+ export * from "./ui/index.js";
2
+ export * from "./utils/index.js";
@@ -0,0 +1,55 @@
1
+ import type { UseChatOptions } from '@ai-sdk/react';
2
+ import type { MantineRadius, MantineSpacing, PaperProps, ScrollAreaProps, StackProps } from '@mantine/core';
3
+ import type { ChatInit, UIMessage } from 'ai';
4
+ import type { ReactNode } from 'react';
5
+ export interface ChatRootProps<TMessage extends UIMessage> extends PaperProps {
6
+ children: ({ message, part, key, }: {
7
+ message: TMessage;
8
+ part: TMessage['parts'][number];
9
+ key: string;
10
+ }) => ReactNode;
11
+ height: string;
12
+ radius?: MantineRadius;
13
+ padding?: MantineSpacing;
14
+ scrollAreaProps?: Omit<ScrollAreaProps, 'children' | 'h'>;
15
+ withScrollButton?: boolean;
16
+ stackProps?: Omit<StackProps, 'p'>;
17
+ emptyComponent?: ReactNode;
18
+ loaderComponent?: ReactNode;
19
+ chatOptions?: UseChatOptions<UIMessage> & ChatInit<UIMessage>;
20
+ }
21
+ /**
22
+ * Корневой компонент чата
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * import { Chat } from '@rolder/kit';
27
+ *
28
+ * const MyChat = () => {
29
+ * return (
30
+ * <Chat.Root h="calc(100vh - 202px)">
31
+ * {(messageIds) => (
32
+ * <>
33
+ * {messageIds.map((messageId) => (
34
+ * <Chat.Message key={messageId} messageId={messageId} />
35
+ * ))}
36
+ *
37
+ * <Chat.Empty />
38
+ * <Chat.Loader />
39
+ * </>
40
+ * )}
41
+ * </Chat.Root>
42
+ * );
43
+ * }
44
+ * ```
45
+ *
46
+ * @param children - Render-функция, принимающая массив ID сообщений
47
+ * @param height - Высота компонента (обязательный параметр)
48
+ * @param radius - Радиус скругления углов компонента
49
+ * @param padding - Отступы внутри компонента
50
+ * @param chatOptions - Опции для инициализации чата (API endpoint, начальные сообщения и т.д.)
51
+ * @param scrollAreaProps - Пропсы для ScrollArea
52
+ * @param withScrollButton - Показывать кнопку прокрутки (по умолчанию true)
53
+ * @param stackProps - Пропсы для Stack контейнера
54
+ */
55
+ export declare const Root: <TMessage extends UIMessage>({ chatOptions, ...props }: ChatRootProps<TMessage>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Messages } from "./messages/index.js";
3
+ import { useInitChat } from "./store/index.js";
4
+ const ChatInitializer = ({ chatOptions })=>{
5
+ useInitChat(chatOptions);
6
+ return null;
7
+ };
8
+ const Root = ({ chatOptions, ...props })=>/*#__PURE__*/ jsxs(Fragment, {
9
+ children: [
10
+ /*#__PURE__*/ jsx(ChatInitializer, {
11
+ chatOptions: chatOptions
12
+ }),
13
+ /*#__PURE__*/ jsx(Messages, {
14
+ ...props
15
+ })
16
+ ]
17
+ });
18
+ export { Root };
@@ -0,0 +1,71 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { ActionIcon, FileButton, Tooltip } from "@mantine/core";
3
+ import { IconPaperclip, IconTrash } from "@tabler/icons-react";
4
+ import { useRef } from "react";
5
+ import { useIsLoading } from "../store/index.js";
6
+ import { FileIcon } from "./FileIcon.js";
7
+ import { getAccept, setFile, useFile, useIsUploading } from "./store/index.js";
8
+ const File = (props)=>{
9
+ const resetRef = useRef(null);
10
+ const isLoading = useIsLoading();
11
+ const isUploading = useIsUploading();
12
+ const file = useFile();
13
+ return /*#__PURE__*/ jsx(FileButton, {
14
+ resetRef: resetRef,
15
+ onChange: async (file)=>{
16
+ if (file) setFile(file);
17
+ },
18
+ accept: getAccept(),
19
+ disabled: isLoading || isUploading,
20
+ ...props,
21
+ children: (props)=>/*#__PURE__*/ jsxs(ActionIcon.Group, {
22
+ children: [
23
+ /*#__PURE__*/ jsx(ActionIcon, {
24
+ size: "lg",
25
+ variant: "default",
26
+ disabled: isLoading,
27
+ loading: isUploading,
28
+ classNames: {
29
+ root: 'rolder-chat-input-file-action-action'
30
+ },
31
+ ...props,
32
+ children: /*#__PURE__*/ jsx(IconPaperclip, {
33
+ size: 24,
34
+ stroke: 1.5
35
+ })
36
+ }),
37
+ file && /*#__PURE__*/ jsxs(Fragment, {
38
+ children: [
39
+ /*#__PURE__*/ jsx(Tooltip, {
40
+ label: file.name,
41
+ openDelay: 500,
42
+ children: /*#__PURE__*/ jsx(ActionIcon.GroupSection, {
43
+ variant: "default",
44
+ size: "lg",
45
+ children: /*#__PURE__*/ jsx(FileIcon, {
46
+ mimeType: file.type
47
+ })
48
+ })
49
+ }),
50
+ /*#__PURE__*/ jsx(ActionIcon, {
51
+ size: "lg",
52
+ variant: "default",
53
+ classNames: {
54
+ root: 'rolder-chat-input-file-action-action'
55
+ },
56
+ onClick: ()=>{
57
+ resetRef.current?.();
58
+ setFile(void 0);
59
+ },
60
+ children: /*#__PURE__*/ jsx(IconTrash, {
61
+ size: 24,
62
+ stroke: 1.5
63
+ })
64
+ })
65
+ ]
66
+ })
67
+ ]
68
+ })
69
+ });
70
+ };
71
+ export { File };
@@ -0,0 +1,43 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { IconFile, IconFileTypeDoc, IconFileTypePdf, IconFileTypePpt, IconFileTypeXls, IconPhoto } from "@tabler/icons-react";
3
+ const FileIcon = ({ mimeType })=>{
4
+ switch(true){
5
+ case mimeType.includes('image/'):
6
+ return /*#__PURE__*/ jsx(IconPhoto, {
7
+ size: 24,
8
+ stroke: 1.5,
9
+ color: "var(--mantine-color-dimmed)"
10
+ });
11
+ case mimeType.includes('application/pdf'):
12
+ return /*#__PURE__*/ jsx(IconFileTypePdf, {
13
+ size: 24,
14
+ stroke: 1.5,
15
+ color: "var(--mantine-color-dimmed)"
16
+ });
17
+ case mimeType.includes('application/vnd.openxmlformats-officedocument.wordprocessingml.document'):
18
+ return /*#__PURE__*/ jsx(IconFileTypeDoc, {
19
+ size: 24,
20
+ stroke: 1.5,
21
+ color: "var(--mantine-color-dimmed)"
22
+ });
23
+ case mimeType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'):
24
+ return /*#__PURE__*/ jsx(IconFileTypeXls, {
25
+ size: 24,
26
+ stroke: 1.5,
27
+ color: "var(--mantine-color-dimmed)"
28
+ });
29
+ case mimeType.includes('application/vnd.openxmlformats-officedocument.presentationml.presentation'):
30
+ return /*#__PURE__*/ jsx(IconFileTypePpt, {
31
+ size: 24,
32
+ stroke: 1.5,
33
+ color: "var(--mantine-color-dimmed)"
34
+ });
35
+ default:
36
+ return /*#__PURE__*/ jsx(IconFile, {
37
+ size: 24,
38
+ stroke: 1.5,
39
+ color: "var(--mantine-color-dimmed)"
40
+ });
41
+ }
42
+ };
43
+ export { FileIcon };
@@ -0,0 +1,9 @@
1
+ import { type PaperProps } from '@mantine/core';
2
+ import { type Accept, type OnSubmitProps } from './store';
3
+ export interface ChatInputRootProps extends PaperProps {
4
+ children?: React.ReactNode;
5
+ onSubmit?: (props: OnSubmitProps) => void;
6
+ isUploading?: boolean;
7
+ accept?: Accept;
8
+ }
9
+ export declare const Root: ({ children, className, onSubmit, isUploading, accept, ...props }: ChatInputRootProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Paper } from "@mantine/core";
3
+ import clsx from "clsx";
4
+ import { useEffect } from "react";
5
+ import { setAccept, setIsUploading, setOnSubmit } from "./store/index.js";
6
+ const Root = ({ children, className, onSubmit, isUploading, accept, ...props })=>{
7
+ useEffect(()=>{
8
+ if (onSubmit) setOnSubmit(onSubmit);
9
+ setIsUploading(isUploading || false);
10
+ if (accept) setAccept(accept);
11
+ }, [
12
+ onSubmit,
13
+ isUploading,
14
+ accept
15
+ ]);
16
+ return /*#__PURE__*/ jsx(Paper, {
17
+ radius: "md",
18
+ withBorder: true,
19
+ className: clsx('rolder-chat-input-root', className),
20
+ ...props,
21
+ children: children
22
+ });
23
+ };
24
+ export { Root };
@@ -0,0 +1,23 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ActionIcon } from "@mantine/core";
3
+ import { IconArrowBigUp } from "@tabler/icons-react";
4
+ import { useIsLoading } from "../store/index.js";
5
+ import { onSubmit, useIsUploading } from "./store/index.js";
6
+ const Submit = ({ children, ...props })=>{
7
+ const Icon = /*#__PURE__*/ jsx(IconArrowBigUp, {
8
+ strokeWidth: 1.5
9
+ });
10
+ const isLoading = useIsLoading();
11
+ const isUploading = useIsUploading();
12
+ return /*#__PURE__*/ jsx(ActionIcon, {
13
+ "aria-label": "Submit",
14
+ variant: "light",
15
+ size: "lg",
16
+ onClick: onSubmit,
17
+ disabled: isUploading,
18
+ loading: isLoading,
19
+ ...props,
20
+ children: children ?? Icon
21
+ });
22
+ };
23
+ export { Submit };
@@ -1,13 +1,14 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Textarea } from "@mantine/core";
3
- import { useState } from "react";
4
- import { usePromptInput } from "./PromptInputContext.js";
3
+ import { useIsLoading } from "../store/index.js";
4
+ import { getIsComposing, onSubmit, setIsComposing, setText, useIsUploading, useText } from "./store/index.js";
5
5
  const Textarea_Textarea = (props)=>{
6
- const { text, setText, onSubmit, submiting, uploading } = usePromptInput();
7
- const [isComposing, setIsComposing] = useState(false);
6
+ const text = useText();
7
+ const isLoading = useIsLoading();
8
+ const isUploading = useIsUploading();
8
9
  const handleKeyDown = (e)=>{
9
10
  if ('Enter' === e.key) {
10
- if (isComposing || e.nativeEvent.isComposing) return;
11
+ if (getIsComposing() || e.nativeEvent.isComposing) return;
11
12
  if (e.shiftKey) return;
12
13
  e.preventDefault();
13
14
  onSubmit();
@@ -18,7 +19,7 @@ const Textarea_Textarea = (props)=>{
18
19
  size: "md",
19
20
  rows: 3,
20
21
  classNames: {
21
- input: 'rolder-prompt-input-textarea'
22
+ input: 'rolder-chat-input-textarea'
22
23
  },
23
24
  placeholder: "Напишите сообщение",
24
25
  onCompositionEnd: ()=>setIsComposing(false),
@@ -26,7 +27,7 @@ const Textarea_Textarea = (props)=>{
26
27
  onKeyDown: handleKeyDown,
27
28
  value: text,
28
29
  onChange: (e)=>setText(e.target.value),
29
- disabled: submiting || uploading,
30
+ disabled: isLoading || isUploading,
30
31
  ...props
31
32
  });
32
33
  };
@@ -1,6 +1,5 @@
1
- export type { Accept, PromptInputProps } from './types';
2
- export declare const PromptInput: {
3
- Root: ({ className, onSubmit, submiting, uploading, accept, ...props }: import("@mantine/core").PaperProps & import("./types").PromptInputProps) => import("react/jsx-runtime").JSX.Element;
1
+ export declare const ChatInput: {
2
+ Root: ({ children, className, onSubmit, isUploading, accept, ...props }: import("./Root").ChatInputRootProps) => import("react/jsx-runtime").JSX.Element;
4
3
  Textarea: (props: import("@mantine/core").TextareaProps) => import("react/jsx-runtime").JSX.Element;
5
4
  Footer: (props: import("@mantine/core").GroupProps) => import("react/jsx-runtime").JSX.Element;
6
5
  Submit: ({ children, ...props }: import("@mantine/core").ActionIconProps) => import("react/jsx-runtime").JSX.Element;
@@ -3,11 +3,11 @@ import { Footer } from "./Footer.js";
3
3
  import { Root } from "./Root.js";
4
4
  import { Submit } from "./Submit.js";
5
5
  import { Textarea } from "./Textarea.js";
6
- const PromptInput = {
6
+ const ChatInput = {
7
7
  Root: Root,
8
8
  Textarea: Textarea,
9
9
  Footer: Footer,
10
10
  Submit: Submit,
11
11
  File: File
12
12
  };
13
- export { PromptInput };
13
+ export { ChatInput };
@@ -0,0 +1,8 @@
1
+ export declare const getFile: () => File | undefined;
2
+ export declare const useFile: () => File | undefined;
3
+ export declare const setFile: (file: File | undefined) => void;
4
+ export declare const useIsUploading: () => boolean;
5
+ export declare const setIsUploading: (isUploading: boolean) => void;
6
+ export type Accept = ('text' | 'image' | 'pdf' | 'word' | 'excel')[];
7
+ export declare const getAccept: () => string;
8
+ export declare const setAccept: (accept: Accept) => void;
@@ -0,0 +1,32 @@
1
+ import { useStore } from "@nanostores/react";
2
+ import { atom } from "nanostores";
3
+ const $file = atom();
4
+ const getFile = ()=>$file.get();
5
+ const useFile = ()=>useStore($file);
6
+ const setFile = (file)=>$file.set(file);
7
+ const $isUploading = atom(false);
8
+ const useIsUploading = ()=>useStore($isUploading);
9
+ const setIsUploading = (isUploading)=>$isUploading.set(isUploading);
10
+ const $accept = atom([
11
+ 'text',
12
+ 'image',
13
+ 'pdf'
14
+ ]);
15
+ const getAccept = ()=>$accept.get().map((type)=>{
16
+ switch(type){
17
+ case 'text':
18
+ return 'text/plain';
19
+ case 'image':
20
+ return 'image/*';
21
+ case 'pdf':
22
+ return 'application/pdf';
23
+ case 'excel':
24
+ return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
25
+ case 'word':
26
+ return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
27
+ default:
28
+ return type;
29
+ }
30
+ }).join(',');
31
+ const setAccept = (accept)=>$accept.set(accept);
32
+ export { getAccept, getFile, setAccept, setFile, setIsUploading, useFile, useIsUploading };
@@ -0,0 +1,2 @@
1
+ import type { ClientUploadError } from '@better-upload/client';
2
+ export declare const fileErrorNotificaton: (error: ClientUploadError) => void;
@@ -0,0 +1,21 @@
1
+ import { notifications } from "@mantine/notifications";
2
+ const serverErrorCodes = {
3
+ unknown: 'Неизвестная ошибка',
4
+ invalid_request: 'Неверный запрос',
5
+ aborted: 'Загрузка прервана',
6
+ rejected: 'Файл отклонен',
7
+ s3_upload: 'Ошибка при загрузке на S3',
8
+ no_files: 'Нет файлов для загрузки',
9
+ file_too_large: 'Один или несколько файлов слишком большие',
10
+ invalid_file_type: 'Один или несколько файлов неверного типа',
11
+ too_many_files: 'Слишком много файлов'
12
+ };
13
+ const fileErrorNotificaton = (error)=>{
14
+ notifications.show({
15
+ title: serverErrorCodes[error.type],
16
+ message: error.message,
17
+ color: 'red',
18
+ autoClose: 5000
19
+ });
20
+ };
21
+ export { fileErrorNotificaton };
@@ -0,0 +1,2 @@
1
+ export * from './file';
2
+ export * from './input';
@@ -0,0 +1,2 @@
1
+ export * from "./file.js";
2
+ export * from "./input.js";
@@ -0,0 +1,13 @@
1
+ import type { FileUIPart } from 'ai';
2
+ export declare const getText: () => string;
3
+ export declare const useText: () => string;
4
+ export declare const setText: (text: string) => void;
5
+ export declare const getIsComposing: () => boolean;
6
+ export declare const setIsComposing: (isComposing: boolean) => void;
7
+ export interface OnSubmitProps {
8
+ text: string;
9
+ file?: FileUIPart;
10
+ }
11
+ export declare const getOnSubmit: () => ((props: OnSubmitProps) => void) | undefined;
12
+ export declare const setOnSubmit: (onSubmit: (props: OnSubmitProps) => void) => void;
13
+ export declare const onSubmit: () => Promise<void>;
@@ -0,0 +1,81 @@
1
+ import { uploadFile } from "@better-upload/client";
2
+ import { useStore } from "@nanostores/react";
3
+ import { nanoid } from "nanoid";
4
+ import { atom } from "nanostores";
5
+ import { getSignedFileUrlFn } from "../../../../../tanstackFunctions/index.js";
6
+ import { addChatMessage, sendMessage } from "../../store/index.js";
7
+ import { getFile } from "./file.js";
8
+ import { fileErrorNotificaton } from "./fileErrorNotificaton.js";
9
+ import { parseExcel, parseWord } from "./parseFile.js";
10
+ const $text = atom('');
11
+ const getText = ()=>$text.get();
12
+ const useText = ()=>useStore($text);
13
+ const setText = (text)=>$text.set(text);
14
+ const $isComposing = atom(false);
15
+ const getIsComposing = ()=>$isComposing.get();
16
+ const setIsComposing = (isComposing)=>$isComposing.set(isComposing);
17
+ const $onSubmit = atom();
18
+ const getOnSubmit = ()=>$onSubmit.get();
19
+ const setOnSubmit = (onSubmit)=>$onSubmit.set(onSubmit);
20
+ const input_onSubmit = async ()=>{
21
+ const onSubmit = getOnSubmit();
22
+ const text = getText();
23
+ const file = getFile();
24
+ let fileUIPart;
25
+ if (file) if ([
26
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
27
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
28
+ ].includes(file.type)) {
29
+ let fileContent;
30
+ let type;
31
+ if ('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' === file.type) {
32
+ fileContent = await parseExcel(file);
33
+ type = 'excel';
34
+ } else if ('application/vnd.openxmlformats-officedocument.wordprocessingml.document' === file.type) {
35
+ fileContent = await parseWord(file);
36
+ type = 'word';
37
+ }
38
+ if (fileContent && type) addChatMessage({
39
+ id: `file-${type}-${nanoid()}`,
40
+ role: 'system',
41
+ parts: [
42
+ {
43
+ type: 'text',
44
+ text: `Пользователь загрузил файл типа "${type}" c содержимым:
45
+ \`\`\`
46
+ ${fileContent}
47
+ \`\`\``
48
+ }
49
+ ]
50
+ });
51
+ } else try {
52
+ const result = await uploadFile({
53
+ file,
54
+ route: 'upload'
55
+ });
56
+ const url = await getSignedFileUrlFn({
57
+ data: {
58
+ s3Key: result.file.objectInfo.key
59
+ }
60
+ });
61
+ fileUIPart = {
62
+ id: nanoid(),
63
+ type: 'file',
64
+ url,
65
+ mediaType: file.type,
66
+ filename: file.name
67
+ };
68
+ } catch (error) {
69
+ fileErrorNotificaton(error);
70
+ }
71
+ if (onSubmit && text.trim()) onSubmit({
72
+ text,
73
+ file: fileUIPart
74
+ });
75
+ if (text.trim()) sendMessage({
76
+ text,
77
+ file: fileUIPart
78
+ });
79
+ setText('');
80
+ };
81
+ export { getIsComposing, getOnSubmit, getText, input_onSubmit as onSubmit, setIsComposing, setOnSubmit, setText, useText };
@@ -0,0 +1,2 @@
1
+ export declare const parseExcel: (file: File) => Promise<string>;
2
+ export declare const parseWord: (file: File) => Promise<string>;
@@ -0,0 +1,23 @@
1
+ import mammoth from "mammoth";
2
+ import { read, utils } from "xlsx";
3
+ const parseExcel = async (file)=>{
4
+ const buffer = await file.arrayBuffer();
5
+ const workbook = read(buffer, {
6
+ type: 'array',
7
+ cellDates: true
8
+ });
9
+ const sheetName = workbook.SheetNames[0];
10
+ const worksheet = workbook.Sheets[sheetName];
11
+ const jsonData = utils.sheet_to_json(worksheet, {
12
+ dateNF: 'yyyy-mm-dd'
13
+ });
14
+ return JSON.stringify(jsonData, null, 2);
15
+ };
16
+ const parseWord = async (file)=>{
17
+ const arrayBuffer = await file.arrayBuffer();
18
+ const { value } = await mammoth.convertToHtml({
19
+ arrayBuffer
20
+ });
21
+ return value;
22
+ };
23
+ export { parseExcel, parseWord };
@@ -0,0 +1,12 @@
1
+ export declare const Chat: {
2
+ Root: <TMessage extends import("ai").UIMessage>({ chatOptions, ...props }: import("./Root").ChatRootProps<TMessage>) => import("react/jsx-runtime").JSX.Element;
3
+ TextPart: ({ messageId, part }: import("./parts").TextPartProps) => import("react/jsx-runtime").JSX.Element;
4
+ ToolPart: <TPart extends import("ai").ToolUIPart = {
5
+ type: `tool-${string}`;
6
+ } & import("ai").UIToolInvocation<import("ai").UITool>>({ children, part, withLoader, loader, onError, }: import("./parts").ToolPartProps<TPart>) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
7
+ ToolExecution: ({ part, onError }: import("./parts/ToolExecution").ToolExecutionProps) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
8
+ FilePart: import("react").MemoExoticComponent<({ part, messageId }: import("./parts/File").FilePartProps) => import("react/jsx-runtime").JSX.Element | null>;
9
+ PartPaper: ({ children, chatRole, ...props }: import("./parts").PartPaperProps) => import("react/jsx-runtime").JSX.Element;
10
+ };
11
+ export { ChatInput } from './chatInput';
12
+ export * from './store';
@@ -0,0 +1,15 @@
1
+ import { PartPaper, TextPart, ToolPart } from "./parts/index.js";
2
+ import { FilePart } from "./parts/File.js";
3
+ import { ToolExecution } from "./parts/ToolExecution.js";
4
+ import { Root } from "./Root.js";
5
+ import { ChatInput } from "./chatInput/index.js";
6
+ export * from "./store/index.js";
7
+ const Chat = {
8
+ Root: Root,
9
+ TextPart: TextPart,
10
+ ToolPart: ToolPart,
11
+ ToolExecution: ToolExecution,
12
+ FilePart: FilePart,
13
+ PartPaper: PartPaper
14
+ };
15
+ export { Chat, ChatInput };
@@ -0,0 +1,4 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare const Empty: ({ emptyComponent }: {
3
+ emptyComponent?: ReactNode;
4
+ }) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Stack, Text } from "@mantine/core";
3
+ import { getIsEmpty } from "../store/index.js";
4
+ const Empty = ({ emptyComponent })=>getIsEmpty() ? emptyComponent ?? /*#__PURE__*/ jsx(Stack, {
5
+ align: "center",
6
+ gap: 0,
7
+ children: /*#__PURE__*/ jsx(Text, {
8
+ children: "Нет сообщений"
9
+ })
10
+ }) : null;
11
+ export { Empty };
@@ -0,0 +1,5 @@
1
+ import { type LoaderProps } from '@mantine/core';
2
+ import type { ReactNode } from 'react';
3
+ export declare const Loader: ({ loaderComponent, ...props }: LoaderProps & {
4
+ loaderComponent?: ReactNode;
5
+ }) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Loader } from "@mantine/core";
3
+ import { useIsLoading } from "../store/index.js";
4
+ const Loader_Loader = ({ loaderComponent, ...props })=>{
5
+ const isLoading = useIsLoading();
6
+ return isLoading ? loaderComponent ?? /*#__PURE__*/ jsx(Loader, {
7
+ size: 28,
8
+ type: "dots",
9
+ ...props
10
+ }) : null;
11
+ };
12
+ export { Loader_Loader as Loader };
@@ -0,0 +1,8 @@
1
+ import { type StackProps } from '@mantine/core';
2
+ import type { UIMessage } from 'ai';
3
+ import type { ChatRootProps } from '../Root';
4
+ export interface MessageProps<TMessage extends UIMessage> extends Omit<StackProps, 'children'> {
5
+ children: ChatRootProps<TMessage>['children'];
6
+ messageId: string;
7
+ }
8
+ export declare const Message: <TMessage extends UIMessage>(props: MessageProps<TMessage>) => React.JSX.Element;
@@ -0,0 +1,22 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Stack } from "@mantine/core";
3
+ import { Fragment, memo } from "react";
4
+ import { getChatMessage, useMessageParts } from "../store/index.js";
5
+ const Message = /*#__PURE__*/ memo(({ children, messageId, ...props })=>{
6
+ const parts = useMessageParts(messageId);
7
+ const message = getChatMessage(messageId);
8
+ return /*#__PURE__*/ jsx(Stack, {
9
+ ...props,
10
+ children: 'function' == typeof children ? parts.map((part, index)=>{
11
+ const key = `${messageId}-${index}`;
12
+ return /*#__PURE__*/ jsx(Fragment, {
13
+ children: children({
14
+ message,
15
+ part,
16
+ key: `${messageId}-${index}`
17
+ })
18
+ }, key);
19
+ }) : null
20
+ });
21
+ }, (oldProps, newProps)=>oldProps.messageId === newProps.messageId);
22
+ export { Message };
@@ -0,0 +1,3 @@
1
+ import type { UIMessage } from 'ai';
2
+ import type { ChatRootProps } from '../Root';
3
+ export declare const Messages: <TMessage extends UIMessage>({ children, height, radius, padding, scrollAreaProps, withScrollButton, stackProps, emptyComponent, loaderComponent, ...props }: Omit<ChatRootProps<TMessage>, "chatOptions">) => import("react/jsx-runtime").JSX.Element;