@rolder/kit 3.0.0-alpha-10 → 3.0.0-alpha-12

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 (109) hide show
  1. package/dist/ai/index.js +2 -0
  2. package/dist/ai/ui/conversation/ConversationContext.js +8 -0
  3. package/dist/ai/ui/conversation/ConversationProvider.js +14 -0
  4. package/dist/ai/ui/conversation/Empty.js +21 -0
  5. package/dist/ai/ui/conversation/File.js +42 -0
  6. package/dist/ai/ui/conversation/FileIcon.js +43 -0
  7. package/dist/ai/ui/conversation/Loader.js +12 -0
  8. package/dist/ai/ui/conversation/Message.js +25 -0
  9. package/dist/ai/ui/conversation/Root.js +26 -0
  10. package/dist/ai/ui/conversation/index.js +15 -0
  11. package/dist/ai/ui/conversation/types.js +0 -0
  12. package/dist/ai/ui/conversation/useChatMessage.js +12 -0
  13. package/dist/ai/ui/index.js +2 -0
  14. package/dist/ai/ui/promptInput/File.js +69 -0
  15. package/dist/ai/ui/promptInput/FileIcon.js +43 -0
  16. package/dist/ai/ui/promptInput/Footer.js +8 -0
  17. package/dist/ai/ui/promptInput/PromptInputContext.js +8 -0
  18. package/dist/ai/ui/promptInput/PromptInputProvider.js +50 -0
  19. package/dist/ai/ui/promptInput/Root.js +18 -0
  20. package/dist/ai/ui/promptInput/Submit.js +21 -0
  21. package/dist/ai/ui/promptInput/Textarea.js +34 -0
  22. package/dist/ai/ui/promptInput/index.js +14 -0
  23. package/dist/ai/ui/promptInput/styles.module.js +7 -0
  24. package/dist/ai/ui/promptInput/styles_module.css +24 -0
  25. package/dist/ai/ui/promptInput/types.js +0 -0
  26. package/dist/ai/utils/convertFileUIPartBlobToDataURL.js +21 -0
  27. package/dist/ai/utils/index.js +2 -0
  28. package/dist/ai/utils/parseAiMessagePart.js +12 -0
  29. package/dist/app/AppDefaults.js +27 -0
  30. package/dist/app/DefaultApp.js +43 -0
  31. package/dist/app/cookieColorSchemeManager.js +46 -0
  32. package/dist/app/defaultRequestMiddlewares.js +24 -0
  33. package/dist/app/defaultTheme.js +24 -0
  34. package/dist/app/index.js +3 -0
  35. package/dist/functions/cookies/getCookie.js +8 -0
  36. package/dist/functions/cookies/index.js +3 -0
  37. package/dist/functions/cookies/setCookie.js +19 -0
  38. package/dist/functions/cookies/setCookies.js +13 -0
  39. package/dist/functions/index.js +1 -0
  40. package/dist/hooks/index.js +2 -0
  41. package/dist/hooks/useMutation.js +8 -0
  42. package/dist/hooks/useMutationWithInvalidate.js +16 -0
  43. package/dist/surreal/connection.js +49 -0
  44. package/dist/surreal/deafaultCrud.js +18 -0
  45. package/dist/surreal/deserialize.js +46 -0
  46. package/dist/surreal/encryption.js +30 -0
  47. package/dist/surreal/index.js +5 -0
  48. package/dist/ui/AnimatedChevron.js +13 -0
  49. package/dist/ui/JsonInput.js +45 -0
  50. package/dist/ui/editor/Content.js +13 -0
  51. package/dist/ui/editor/Provider.js +80 -0
  52. package/dist/ui/editor/Root.js +19 -0
  53. package/dist/ui/editor/Toolbar.js +138 -0
  54. package/dist/ui/editor/index.js +11 -0
  55. package/dist/ui/editor/styles.module.js +7 -0
  56. package/dist/ui/editor/styles_module.css +16 -0
  57. package/dist/ui/editor/types.js +0 -0
  58. package/dist/ui/error/DefaultError.js +62 -0
  59. package/dist/ui/error/DefaultNotFound.js +37 -0
  60. package/dist/ui/error/Forbidden.js +32 -0
  61. package/dist/ui/error/defaultErrorNotification.js +8 -0
  62. package/dist/ui/error/index.js +4 -0
  63. package/dist/ui/form/blurOnError.js +11 -0
  64. package/dist/ui/form/buttons/CancelButton.js +22 -0
  65. package/dist/ui/form/buttons/SubmitButton.js +22 -0
  66. package/dist/ui/form/buttons/SubscribeActionIcon.js +15 -0
  67. package/dist/ui/form/buttons/SubscribeButton.js +16 -0
  68. package/dist/ui/form/buttons/index.js +4 -0
  69. package/dist/ui/form/context.js +26 -0
  70. package/dist/ui/form/fields/JsonField.js +13 -0
  71. package/dist/ui/form/fields/MultiSelectField.js +15 -0
  72. package/dist/ui/form/fields/NumberField.js +15 -0
  73. package/dist/ui/form/fields/PassowrdField.js +18 -0
  74. package/dist/ui/form/fields/SelectField.js +15 -0
  75. package/dist/ui/form/fields/SwitchField.js +15 -0
  76. package/dist/ui/form/fields/TextField.js +15 -0
  77. package/dist/ui/form/fields/TextPassowrdField.js +29 -0
  78. package/dist/ui/form/fields/TextareaField.js +15 -0
  79. package/dist/ui/form/fields/index.js +9 -0
  80. package/dist/ui/form/fieldsSchema.js +13 -0
  81. package/dist/ui/form/index.js +4 -0
  82. package/dist/ui/hoverPaper/HoverPaper.js +16 -0
  83. package/dist/ui/hoverPaper/index.js +2 -0
  84. package/dist/ui/hoverPaper/styles.module.js +5 -0
  85. package/dist/ui/hoverPaper/styles_module.css +15 -0
  86. package/dist/ui/hoverPaper/usePaperHover.js +9 -0
  87. package/dist/ui/index.js +9 -0
  88. package/dist/ui/routerLink/RouterLink.js +37 -0
  89. package/dist/ui/routerLink/index.js +1 -0
  90. package/dist/ui/routerLink/styles.module.js +5 -0
  91. package/dist/ui/routerLink/styles_module.css +5 -0
  92. package/dist/ui/saveInput/JsonInput.js +34 -0
  93. package/dist/ui/saveInput/NumberInput.js +27 -0
  94. package/dist/ui/saveInput/SaveInput.js +15 -0
  95. package/dist/ui/saveInput/Select.js +27 -0
  96. package/dist/ui/saveInput/Switch.js +30 -0
  97. package/dist/ui/saveInput/TextInput.js +26 -0
  98. package/dist/ui/saveInput/Textarea.js +26 -0
  99. package/dist/ui/saveInput/index.js +2 -0
  100. package/dist/ui/scrollArea/ScrollArea.js +30 -0
  101. package/dist/ui/scrollArea/ScrollAreaButton.js +30 -0
  102. package/dist/ui/scrollArea/ScrollAreaContent.js +30 -0
  103. package/dist/ui/scrollArea/context.js +10 -0
  104. package/dist/ui/scrollArea/index.js +3 -0
  105. package/dist/ui/scrollArea/styles.module.js +7 -0
  106. package/dist/ui/scrollArea/styles_module.css +14 -0
  107. package/dist/ui/scrollArea/types.js +0 -0
  108. package/dist/ui/scrollArea/useScrollArea.js +146 -0
  109. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export * from "./ui/index.js";
2
+ export * from "./utils/index.js";
@@ -0,0 +1,8 @@
1
+ import { createContext, useContext } from "react";
2
+ const ConversationContext = createContext(null);
3
+ const useConversation = ()=>{
4
+ const context = useContext(ConversationContext);
5
+ if (!context) throw new Error('useConversation must be used within a ConversationProvider');
6
+ return context;
7
+ };
8
+ export { ConversationContext, useConversation };
@@ -0,0 +1,14 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ConversationContext } from "./ConversationContext.js";
3
+ const Provider = ({ children, loading, streaming, empty })=>{
4
+ const value = {
5
+ loading,
6
+ streaming,
7
+ empty
8
+ };
9
+ return /*#__PURE__*/ jsx(ConversationContext.Provider, {
10
+ value: value,
11
+ children: children
12
+ });
13
+ };
14
+ export { Provider };
@@ -0,0 +1,21 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Stack, Text } from "@mantine/core";
3
+ import { useConversation } from "./ConversationContext.js";
4
+ const Empty = ()=>{
5
+ const { empty } = useConversation();
6
+ return empty ? null : /*#__PURE__*/ jsxs(Stack, {
7
+ align: "center",
8
+ gap: 0,
9
+ children: [
10
+ /*#__PURE__*/ jsx(Text, {
11
+ children: "Нет сообщений"
12
+ }),
13
+ /*#__PURE__*/ jsx(Text, {
14
+ size: "sm",
15
+ c: "dimmed",
16
+ children: "Начните общение, чтобы увидеть сообщения здесь"
17
+ })
18
+ ]
19
+ });
20
+ };
21
+ export { Empty };
@@ -0,0 +1,42 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Image, Paper } from "@mantine/core";
3
+ import { FileIcon } from "./FileIcon.js";
4
+ const File = ({ message })=>{
5
+ const textFileType = message.id.split('-')[1];
6
+ const fileParts = message.parts?.filter((i)=>'file' === i.type);
7
+ const lastFilePart = fileParts[fileParts.length - 1];
8
+ const FileComponent = ()=>{
9
+ switch(textFileType){
10
+ case 'excel':
11
+ return /*#__PURE__*/ jsx(FileIcon, {
12
+ mimeType: "excel"
13
+ });
14
+ case 'word':
15
+ return /*#__PURE__*/ jsx(FileIcon, {
16
+ mimeType: "word"
17
+ });
18
+ case 'powerpoint':
19
+ return /*#__PURE__*/ jsx(FileIcon, {
20
+ mimeType: "powerpoint"
21
+ });
22
+ }
23
+ if (lastFilePart.mediaType.includes('image/')) return /*#__PURE__*/ jsx(Image, {
24
+ radius: "md",
25
+ h: 128,
26
+ src: lastFilePart.url,
27
+ alt: "Image Preview"
28
+ });
29
+ return /*#__PURE__*/ jsx(FileIcon, {
30
+ mimeType: lastFilePart.mediaType
31
+ });
32
+ };
33
+ return textFileType || lastFilePart ? /*#__PURE__*/ jsx(Paper, {
34
+ radius: "md",
35
+ px: "md",
36
+ py: "sm",
37
+ ml: "auto",
38
+ bg: "var(--mantine-color-default-hover)",
39
+ children: /*#__PURE__*/ jsx(FileComponent, {})
40
+ }) : null;
41
+ };
42
+ 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: 36,
8
+ stroke: 1.5,
9
+ color: "var(--mantine-color-text)"
10
+ });
11
+ case mimeType.includes('application/pdf'):
12
+ return /*#__PURE__*/ jsx(IconFileTypePdf, {
13
+ size: 36,
14
+ stroke: 1.5,
15
+ color: "var(--mantine-color-text)"
16
+ });
17
+ case 'word' === mimeType:
18
+ return /*#__PURE__*/ jsx(IconFileTypeDoc, {
19
+ size: 36,
20
+ stroke: 1.5,
21
+ color: "var(--mantine-color-text)"
22
+ });
23
+ case 'excel' === mimeType:
24
+ return /*#__PURE__*/ jsx(IconFileTypeXls, {
25
+ size: 36,
26
+ stroke: 1.5,
27
+ color: "var(--mantine-color-text)"
28
+ });
29
+ case 'powerpoint' === mimeType:
30
+ return /*#__PURE__*/ jsx(IconFileTypePpt, {
31
+ size: 36,
32
+ stroke: 1.5,
33
+ color: "var(--mantine-color-text)"
34
+ });
35
+ default:
36
+ return /*#__PURE__*/ jsx(IconFile, {
37
+ size: 36,
38
+ stroke: 1.5,
39
+ color: "var(--mantine-color-text)"
40
+ });
41
+ }
42
+ };
43
+ export { FileIcon };
@@ -0,0 +1,12 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Loader } from "@mantine/core";
3
+ import { useConversation } from "./ConversationContext.js";
4
+ const Loader_Loader = (props)=>{
5
+ const { loading } = useConversation();
6
+ return loading ? /*#__PURE__*/ jsx(Loader, {
7
+ size: 28,
8
+ type: "dots",
9
+ ...props
10
+ }) : null;
11
+ };
12
+ export { Loader_Loader as Loader };
@@ -0,0 +1,25 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Paper } from "@mantine/core";
3
+ import { Streamdown } from "streamdown";
4
+ import { useConversation } from "./ConversationContext.js";
5
+ import { useChatMessage } from "./useChatMessage.js";
6
+ const Message = ({ message })=>{
7
+ const textParts = message?.parts?.filter((i)=>'text' === i.type);
8
+ const lastTextPart = textParts?.[textParts.length - 1];
9
+ const chatMessage = useChatMessage(lastTextPart);
10
+ const { streaming } = useConversation();
11
+ return chatMessage && 'system' !== message.role ? /*#__PURE__*/ jsx(Paper, {
12
+ radius: "md",
13
+ px: "md",
14
+ py: "sm",
15
+ maw: "80%",
16
+ ml: 'user' === message.role ? 'auto' : void 0,
17
+ bg: 'user' === message.role ? 'var(--mantine-color-default-hover)' : 'var(--mantine-primary-color-light)',
18
+ fz: "sm",
19
+ children: /*#__PURE__*/ jsx(Streamdown, {
20
+ isAnimating: streaming && 'assistant' === message.role,
21
+ children: chatMessage
22
+ })
23
+ }) : null;
24
+ };
25
+ export { Message };
@@ -0,0 +1,26 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Paper, Stack } from "@mantine/core";
3
+ import { ScrollArea } from "../../../ui/index.js";
4
+ import { Provider } from "./ConversationProvider.js";
5
+ const Root = ({ children, loading, streaming, empty, ...props })=>/*#__PURE__*/ jsx(Provider, {
6
+ loading: loading,
7
+ streaming: streaming,
8
+ empty: empty,
9
+ children: /*#__PURE__*/ jsx(Paper, {
10
+ withBorder: true,
11
+ radius: "md",
12
+ ...props,
13
+ children: /*#__PURE__*/ jsxs(ScrollArea, {
14
+ autoScroll: true,
15
+ scrollToBottomOnInit: true,
16
+ p: "md",
17
+ children: [
18
+ /*#__PURE__*/ jsx(Stack, {
19
+ children: children
20
+ }),
21
+ /*#__PURE__*/ jsx(ScrollArea.ScrollButton, {})
22
+ ]
23
+ })
24
+ })
25
+ });
26
+ export { Root };
@@ -0,0 +1,15 @@
1
+ import { Empty } from "./Empty.js";
2
+ import { File } from "./File.js";
3
+ import { Loader } from "./Loader.js";
4
+ import { Message } from "./Message.js";
5
+ import { Root } from "./Root.js";
6
+ export * from "./types.js";
7
+ export * from "./useChatMessage.js";
8
+ const Conversation = {
9
+ Root: Root,
10
+ Message: Message,
11
+ File: File,
12
+ Loader: Loader,
13
+ Empty: Empty
14
+ };
15
+ export { Conversation };
File without changes
@@ -0,0 +1,12 @@
1
+ import { useEffect, useState } from "react";
2
+ import { parseAiMessagePart } from "../../utils/index.js";
3
+ const useChatMessage = (part)=>{
4
+ const [parsedText, setParsedText] = useState('');
5
+ useEffect(()=>{
6
+ parseAiMessagePart(part).then((i)=>setParsedText(i.text));
7
+ }, [
8
+ part
9
+ ]);
10
+ return parsedText;
11
+ };
12
+ export { useChatMessage };
@@ -0,0 +1,2 @@
1
+ export * from "./conversation/index.js";
2
+ export * from "./promptInput/index.js";
@@ -0,0 +1,69 @@
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 { FileIcon } from "./FileIcon.js";
6
+ import { usePromptInput } from "./PromptInputContext.js";
7
+ import styles_module from "./styles.module.js";
8
+ const File = (props)=>{
9
+ const resetRef = useRef(null);
10
+ const { file, setFile, accept, submiting, uploading } = usePromptInput();
11
+ return /*#__PURE__*/ jsx(FileButton, {
12
+ resetRef: resetRef,
13
+ onChange: async (file)=>{
14
+ if (file) setFile(file);
15
+ },
16
+ accept: accept,
17
+ disabled: submiting || uploading,
18
+ ...props,
19
+ children: (props)=>/*#__PURE__*/ jsxs(ActionIcon.Group, {
20
+ children: [
21
+ /*#__PURE__*/ jsx(ActionIcon, {
22
+ size: "lg",
23
+ variant: "default",
24
+ disabled: submiting,
25
+ loading: uploading,
26
+ classNames: {
27
+ root: styles_module.fileActionAction
28
+ },
29
+ ...props,
30
+ children: /*#__PURE__*/ jsx(IconPaperclip, {
31
+ size: 24,
32
+ stroke: 1.5
33
+ })
34
+ }),
35
+ file && /*#__PURE__*/ jsxs(Fragment, {
36
+ children: [
37
+ /*#__PURE__*/ jsx(Tooltip, {
38
+ label: file.name,
39
+ openDelay: 500,
40
+ children: /*#__PURE__*/ jsx(ActionIcon.GroupSection, {
41
+ variant: "default",
42
+ size: "lg",
43
+ children: /*#__PURE__*/ jsx(FileIcon, {
44
+ mimeType: file.type
45
+ })
46
+ })
47
+ }),
48
+ /*#__PURE__*/ jsx(ActionIcon, {
49
+ size: "lg",
50
+ variant: "default",
51
+ classNames: {
52
+ root: styles_module.fileActionAction
53
+ },
54
+ onClick: ()=>{
55
+ resetRef.current?.();
56
+ setFile(void 0);
57
+ },
58
+ children: /*#__PURE__*/ jsx(IconTrash, {
59
+ size: 24,
60
+ stroke: 1.5
61
+ })
62
+ })
63
+ ]
64
+ })
65
+ ]
66
+ })
67
+ });
68
+ };
69
+ 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,8 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Group } from "@mantine/core";
3
+ const Footer = (props)=>/*#__PURE__*/ jsx(Group, {
4
+ justify: "space-between",
5
+ p: "xs",
6
+ ...props
7
+ });
8
+ export { Footer };
@@ -0,0 +1,8 @@
1
+ import { createContext, useContext } from "react";
2
+ const PromptInputContext = createContext(null);
3
+ const usePromptInput = ()=>{
4
+ const context = useContext(PromptInputContext);
5
+ if (!context) throw new Error('usePromptInput must be used within a PromptInputProvider');
6
+ return context;
7
+ };
8
+ export { PromptInputContext, usePromptInput };
@@ -0,0 +1,50 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { PromptInputContext } from "./PromptInputContext.js";
4
+ const Provider = ({ children, onSubmit, submiting, uploading, accept = [
5
+ 'text',
6
+ 'image',
7
+ 'pdf'
8
+ ] })=>{
9
+ const [text, setText] = useState('');
10
+ const [file, setFile] = useState();
11
+ const value = {
12
+ text,
13
+ setText,
14
+ file,
15
+ setFile,
16
+ onSubmit: ()=>{
17
+ if (text.trim()) {
18
+ onSubmit({
19
+ text: text.trim(),
20
+ file
21
+ });
22
+ setText('');
23
+ setFile(void 0);
24
+ }
25
+ },
26
+ submiting,
27
+ uploading,
28
+ accept: accept.map((type)=>{
29
+ switch(type){
30
+ case 'text':
31
+ return 'text/plain';
32
+ case 'image':
33
+ return 'image/*';
34
+ case 'pdf':
35
+ return 'application/pdf';
36
+ case 'excel':
37
+ return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
38
+ case 'word':
39
+ return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
40
+ default:
41
+ return type;
42
+ }
43
+ }).join(',')
44
+ };
45
+ return /*#__PURE__*/ jsx(PromptInputContext.Provider, {
46
+ value: value,
47
+ children: children
48
+ });
49
+ };
50
+ export { Provider };
@@ -0,0 +1,18 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Paper } from "@mantine/core";
3
+ import clsx from "clsx";
4
+ import { Provider } from "./PromptInputProvider.js";
5
+ import styles_module from "./styles.module.js";
6
+ const Root = ({ className, onSubmit, submiting, uploading, accept, ...props })=>/*#__PURE__*/ jsx(Provider, {
7
+ onSubmit: onSubmit,
8
+ submiting: submiting,
9
+ uploading: uploading,
10
+ accept: accept,
11
+ children: /*#__PURE__*/ jsx(Paper, {
12
+ radius: "md",
13
+ withBorder: true,
14
+ className: clsx(styles_module.root, className),
15
+ ...props
16
+ })
17
+ });
18
+ export { Root };
@@ -0,0 +1,21 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ActionIcon } from "@mantine/core";
3
+ import { IconArrowBigUp } from "@tabler/icons-react";
4
+ import { usePromptInput } from "./PromptInputContext.js";
5
+ const Submit = ({ children, ...props })=>{
6
+ const Icon = /*#__PURE__*/ jsx(IconArrowBigUp, {
7
+ strokeWidth: 1.5
8
+ });
9
+ const { onSubmit, submiting, uploading } = usePromptInput();
10
+ return /*#__PURE__*/ jsx(ActionIcon, {
11
+ "aria-label": "Submit",
12
+ variant: "light",
13
+ size: "lg",
14
+ onClick: onSubmit,
15
+ disabled: uploading,
16
+ loading: submiting,
17
+ ...props,
18
+ children: children ?? Icon
19
+ });
20
+ };
21
+ export { Submit };
@@ -0,0 +1,34 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Textarea } from "@mantine/core";
3
+ import { useState } from "react";
4
+ import { usePromptInput } from "./PromptInputContext.js";
5
+ import styles_module from "./styles.module.js";
6
+ const Textarea_Textarea = (props)=>{
7
+ const { text, setText, onSubmit, submiting, uploading } = usePromptInput();
8
+ const [isComposing, setIsComposing] = useState(false);
9
+ const handleKeyDown = (e)=>{
10
+ if ('Enter' === e.key) {
11
+ if (isComposing || e.nativeEvent.isComposing) return;
12
+ if (e.shiftKey) return;
13
+ e.preventDefault();
14
+ onSubmit();
15
+ }
16
+ };
17
+ return /*#__PURE__*/ jsx(Textarea, {
18
+ w: "100%",
19
+ size: "md",
20
+ rows: 3,
21
+ classNames: {
22
+ input: styles_module.textarea
23
+ },
24
+ placeholder: "Напишите сообщение",
25
+ onCompositionEnd: ()=>setIsComposing(false),
26
+ onCompositionStart: ()=>setIsComposing(true),
27
+ onKeyDown: handleKeyDown,
28
+ value: text,
29
+ onChange: (e)=>setText(e.target.value),
30
+ disabled: submiting || uploading,
31
+ ...props
32
+ });
33
+ };
34
+ export { Textarea_Textarea as Textarea };
@@ -0,0 +1,14 @@
1
+ import { File } from "./File.js";
2
+ import { Footer } from "./Footer.js";
3
+ import { Root } from "./Root.js";
4
+ import { Submit } from "./Submit.js";
5
+ import { Textarea } from "./Textarea.js";
6
+ export * from "./types.js";
7
+ const PromptInput = {
8
+ Root: Root,
9
+ Textarea: Textarea,
10
+ Footer: Footer,
11
+ Submit: Submit,
12
+ File: File
13
+ };
14
+ export { PromptInput };
@@ -0,0 +1,7 @@
1
+ import "./styles_module.css";
2
+ const styles_module = {
3
+ root: "root-gmXOO2",
4
+ textarea: "textarea-f3Dbtf",
5
+ fileActionAction: "fileActionAction-w3KPzA"
6
+ };
7
+ export { styles_module as default };
@@ -0,0 +1,24 @@
1
+ .root-gmXOO2 {
2
+ background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
3
+
4
+ &:focus-within {
5
+ border-color: var(--mantine-primary-color-filled);
6
+ border-color: var(--mantine-primary-color-filled);
7
+ outline: none;
8
+ }
9
+ }
10
+
11
+ .textarea-f3Dbtf {
12
+ border: 0;
13
+ border-radius: 8px;
14
+ overflow: hidden;
15
+ }
16
+
17
+ .fileActionAction-w3KPzA {
18
+ color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
19
+
20
+ &[data-disabled] {
21
+ color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
22
+ }
23
+ }
24
+
File without changes
@@ -0,0 +1,21 @@
1
+ async function blobToDataURL(blobUrl) {
2
+ const response = await fetch(blobUrl);
3
+ const blob = await response.blob();
4
+ return new Promise((resolve, reject)=>{
5
+ const reader = new FileReader();
6
+ reader.onload = ()=>resolve(reader.result);
7
+ reader.onerror = reject;
8
+ reader.readAsDataURL(blob);
9
+ });
10
+ }
11
+ async function convertFileUIPartBlobToDataURL(file) {
12
+ if (file.url.startsWith('blob:')) {
13
+ const dataUrl = await blobToDataURL(file.url);
14
+ return {
15
+ ...file,
16
+ url: dataUrl
17
+ };
18
+ }
19
+ return file;
20
+ }
21
+ export { convertFileUIPartBlobToDataURL };
@@ -0,0 +1,2 @@
1
+ export * from "./convertFileUIPartBlobToDataURL.js";
2
+ export * from "./parseAiMessagePart.js";
@@ -0,0 +1,12 @@
1
+ import { parsePartialJson } from "ai";
2
+ const parseAiMessagePart = async (part)=>{
3
+ if (!part.text.startsWith('{')) return part;
4
+ try {
5
+ const result = await parsePartialJson(part.text);
6
+ return result?.value || part;
7
+ } catch (error) {
8
+ console.error('Error parsing partial JSON:', error);
9
+ return part;
10
+ }
11
+ };
12
+ export { parseAiMessagePart };
@@ -0,0 +1,27 @@
1
+ import { useComputedColorScheme } from "@mantine/core";
2
+ import { useEffect } from "react";
3
+ import { setCookies } from "../functions/index.js";
4
+ const AppDefaults = ({ saveColorScheme })=>{
5
+ const colorScheme = useComputedColorScheme();
6
+ useEffect(()=>{
7
+ const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
8
+ const cookies = [
9
+ {
10
+ name: 'tz',
11
+ value: tz,
12
+ expires: 365
13
+ }
14
+ ];
15
+ if (saveColorScheme) cookies.push({
16
+ name: 'colorScheme',
17
+ value: colorScheme,
18
+ expires: 365
19
+ });
20
+ setCookies(cookies);
21
+ }, [
22
+ colorScheme,
23
+ saveColorScheme
24
+ ]);
25
+ return null;
26
+ };
27
+ export { AppDefaults };