@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,16 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Paper } from "@mantine/core";
3
+ import { forwardRef } from "react";
4
+ import styles_module from "./styles.module.js";
5
+ const HoverPaper = /*#__PURE__*/ forwardRef(({ disabled, classNames, ...props }, ref)=>/*#__PURE__*/ jsx(Paper, {
6
+ ref: ref,
7
+ classNames: {
8
+ root: styles_module.root,
9
+ ...classNames
10
+ },
11
+ mod: {
12
+ disabled
13
+ },
14
+ ...props
15
+ }));
16
+ export { HoverPaper };
@@ -0,0 +1,2 @@
1
+ export * from "./HoverPaper.js";
2
+ export * from "./usePaperHover.js";
@@ -0,0 +1,5 @@
1
+ import "./styles_module.css";
2
+ const styles_module = {
3
+ root: "root-aYPBH7"
4
+ };
5
+ export { styles_module as default };
@@ -0,0 +1,15 @@
1
+ .root-aYPBH7 {
2
+ transition: background-color .2s ease-in-out;
3
+
4
+ &:hover {
5
+ background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
6
+ cursor: pointer;
7
+ transition: background-color .2s ease-in-out;
8
+ }
9
+
10
+ &[data-disabled] {
11
+ background-color: unset;
12
+ cursor: default;
13
+ }
14
+ }
15
+
@@ -0,0 +1,9 @@
1
+ import { useHover } from "@mantine/hooks";
2
+ const usePaperHover = ()=>{
3
+ const { hovered: paperHovered, ref: paperRef } = useHover();
4
+ return {
5
+ paperHovered,
6
+ paperRef
7
+ };
8
+ };
9
+ export { usePaperHover };
@@ -0,0 +1,9 @@
1
+ export * from "./AnimatedChevron.js";
2
+ export * from "./editor/index.js";
3
+ export * from "./error/index.js";
4
+ export * from "./form/index.js";
5
+ export * from "./hoverPaper/index.js";
6
+ export * from "./JsonInput.js";
7
+ export * from "./routerLink/index.js";
8
+ export * from "./saveInput/index.js";
9
+ export * from "./scrollArea/index.js";
@@ -0,0 +1,37 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ActionIcon, Anchor, Button, UnstyledButton } from "@mantine/core";
3
+ import { createLink } from "@tanstack/react-router";
4
+ import { forwardRef } from "react";
5
+ import styles_module from "./styles.module.js";
6
+ const MantineLinkComponent = /*#__PURE__*/ forwardRef(({ classNames, ...props }, ref)=>/*#__PURE__*/ jsx(Anchor, {
7
+ ref: ref,
8
+ classNames: {
9
+ root: styles_module.root,
10
+ ...classNames
11
+ },
12
+ c: "inherit",
13
+ underline: "never",
14
+ ...props
15
+ }));
16
+ const MantineButtonComponent = /*#__PURE__*/ forwardRef((props, ref)=>/*#__PURE__*/ jsx(Button, {
17
+ ref: ref,
18
+ ...props
19
+ }));
20
+ const MantineActionIconComponent = /*#__PURE__*/ forwardRef((props, ref)=>/*#__PURE__*/ jsx(ActionIcon, {
21
+ ref: ref,
22
+ ...props
23
+ }));
24
+ const MantineUnstyledButtonComponent = /*#__PURE__*/ forwardRef((props, ref)=>/*#__PURE__*/ jsx(UnstyledButton, {
25
+ ref: ref,
26
+ ...props
27
+ }));
28
+ const RouterLinkBase = createLink(MantineLinkComponent);
29
+ const RouterLinkButton = createLink(MantineButtonComponent);
30
+ const RouterLinkActionIcon = createLink(MantineActionIconComponent);
31
+ const RouterLinkUnstyledButton = createLink(MantineUnstyledButtonComponent);
32
+ const RouterLink = Object.assign(RouterLinkBase, {
33
+ Button: RouterLinkButton,
34
+ ActionIcon: RouterLinkActionIcon,
35
+ UnstyledButton: RouterLinkUnstyledButton
36
+ });
37
+ export { RouterLink };
@@ -0,0 +1 @@
1
+ export * from "./RouterLink.js";
@@ -0,0 +1,5 @@
1
+ import "./styles_module.css";
2
+ const styles_module = {
3
+ root: "root-t5Mcrb"
4
+ };
5
+ export { styles_module as default };
@@ -0,0 +1,5 @@
1
+ .root-t5Mcrb {
2
+ color: inherit;
3
+ text-decoration: none;
4
+ }
5
+
@@ -0,0 +1,34 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box, Loader } from "@mantine/core";
3
+ import { useDebouncedCallback } from "@mantine/hooks";
4
+ import { useState } from "react";
5
+ import { JsonInput } from "../JsonInput.js";
6
+ const JsonInput_JsonInput = ({ initialValue, onChange, debounce = 300, ...props })=>{
7
+ const [value, setValue] = useState(initialValue);
8
+ const [loading, setLoading] = useState(false);
9
+ const handleSave = useDebouncedCallback(async (content)=>{
10
+ setLoading(true);
11
+ await onChange(content);
12
+ setLoading(false);
13
+ }, debounce);
14
+ return /*#__PURE__*/ jsxs(Box, {
15
+ pos: "relative",
16
+ children: [
17
+ /*#__PURE__*/ jsx(JsonInput, {
18
+ value: value,
19
+ onChange: (e)=>{
20
+ setValue(e);
21
+ handleSave(e);
22
+ },
23
+ ...props
24
+ }),
25
+ loading && /*#__PURE__*/ jsx(Loader, {
26
+ size: "sm",
27
+ pos: "absolute",
28
+ top: 8,
29
+ left: 8
30
+ })
31
+ ]
32
+ });
33
+ };
34
+ export { JsonInput_JsonInput as JsonInput };
@@ -0,0 +1,27 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Loader, NumberInput } from "@mantine/core";
3
+ import { useDebouncedCallback } from "@mantine/hooks";
4
+ import { useState } from "react";
5
+ const NumberInput_NumberInput = ({ initialValue, onChange, debounce = 300, ...props })=>{
6
+ const [value, setValue] = useState(initialValue);
7
+ const [loading, setLoading] = useState(false);
8
+ const handleSave = useDebouncedCallback(async (content)=>{
9
+ setLoading(true);
10
+ await onChange(content);
11
+ setLoading(false);
12
+ }, debounce);
13
+ return /*#__PURE__*/ jsx(NumberInput, {
14
+ value: value,
15
+ onChange: (v)=>{
16
+ setValue(v);
17
+ handleSave(v);
18
+ },
19
+ flex: props.w ? void 0 : 1,
20
+ rightSection: loading ? /*#__PURE__*/ jsx(Loader, {
21
+ size: "sm",
22
+ mr: 8
23
+ }) : void 0,
24
+ ...props
25
+ });
26
+ };
27
+ export { NumberInput_NumberInput as NumberInput };
@@ -0,0 +1,15 @@
1
+ import { JsonInput } from "./JsonInput.js";
2
+ import { NumberInput } from "./NumberInput.js";
3
+ import { Select } from "./Select.js";
4
+ import { Switch } from "./Switch.js";
5
+ import { Textarea } from "./Textarea.js";
6
+ import { TextInput } from "./TextInput.js";
7
+ const SaveInput = Object.assign(TextInput, {
8
+ TextInput: TextInput,
9
+ NumberInput: NumberInput,
10
+ Textarea: Textarea,
11
+ Switch: Switch,
12
+ JsonInput: JsonInput,
13
+ Select: Select
14
+ });
15
+ export { SaveInput };
@@ -0,0 +1,27 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Loader, Select } from "@mantine/core";
3
+ import { useDebouncedCallback } from "@mantine/hooks";
4
+ import { useState } from "react";
5
+ const Select_Select = ({ initialValue, onChange, debounce = 300, ...props })=>{
6
+ const [value, setValue] = useState(initialValue);
7
+ const [loading, setLoading] = useState(false);
8
+ const handleSave = useDebouncedCallback(async (content)=>{
9
+ setLoading(true);
10
+ await onChange(content);
11
+ setLoading(false);
12
+ }, debounce);
13
+ return /*#__PURE__*/ jsx(Select, {
14
+ value: value,
15
+ onChange: (v)=>{
16
+ setValue(v);
17
+ handleSave(v);
18
+ },
19
+ flex: props.w ? void 0 : 1,
20
+ disabled: loading,
21
+ rightSection: loading ? /*#__PURE__*/ jsx(Loader, {
22
+ size: "sm"
23
+ }) : void 0,
24
+ ...props
25
+ });
26
+ };
27
+ export { Select_Select as Select };
@@ -0,0 +1,30 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Box, Loader, Switch } from "@mantine/core";
3
+ import { useDebouncedCallback } from "@mantine/hooks";
4
+ import { useState } from "react";
5
+ const Switch_Switch = ({ initialValue, onChange, debounce = 300, w, ...props })=>{
6
+ const [value, setValue] = useState(initialValue);
7
+ const [loading, setLoading] = useState(false);
8
+ const handleSave = useDebouncedCallback(async (content)=>{
9
+ setLoading(true);
10
+ await onChange(content);
11
+ setLoading(false);
12
+ }, debounce);
13
+ return /*#__PURE__*/ jsx(Box, {
14
+ flex: 1,
15
+ w: w,
16
+ children: loading ? /*#__PURE__*/ jsx(Loader, {
17
+ size: "sm",
18
+ mt: 6.5,
19
+ ml: 8
20
+ }) : /*#__PURE__*/ jsx(Switch, {
21
+ checked: value,
22
+ onChange: (e)=>{
23
+ setValue(e.currentTarget.checked);
24
+ handleSave(e.currentTarget.checked);
25
+ },
26
+ ...props
27
+ })
28
+ });
29
+ };
30
+ export { Switch_Switch as Switch };
@@ -0,0 +1,26 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Loader, TextInput } from "@mantine/core";
3
+ import { useDebouncedCallback } from "@mantine/hooks";
4
+ import { useState } from "react";
5
+ const TextInput_TextInput = ({ initialValue, onChange, debounce = 300, ...props })=>{
6
+ const [value, setValue] = useState(initialValue || '');
7
+ const [loading, setLoading] = useState(false);
8
+ const handleSave = useDebouncedCallback(async (content)=>{
9
+ setLoading(true);
10
+ await onChange(content);
11
+ setLoading(false);
12
+ }, debounce);
13
+ return /*#__PURE__*/ jsx(TextInput, {
14
+ value: value,
15
+ onChange: (e)=>{
16
+ setValue(e.target.value);
17
+ handleSave(e.target.value);
18
+ },
19
+ flex: props.w ? void 0 : 1,
20
+ rightSection: loading ? /*#__PURE__*/ jsx(Loader, {
21
+ size: "sm"
22
+ }) : void 0,
23
+ ...props
24
+ });
25
+ };
26
+ export { TextInput_TextInput as TextInput };
@@ -0,0 +1,26 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Loader, Textarea } from "@mantine/core";
3
+ import { useDebouncedCallback } from "@mantine/hooks";
4
+ import { useState } from "react";
5
+ const Textarea_Textarea = ({ initialValue, onChange, debounce = 300, ...props })=>{
6
+ const [value, setValue] = useState(initialValue);
7
+ const [loading, setLoading] = useState(false);
8
+ const handleSave = useDebouncedCallback(async (content)=>{
9
+ setLoading(true);
10
+ await onChange(content);
11
+ setLoading(false);
12
+ }, debounce);
13
+ return /*#__PURE__*/ jsx(Textarea, {
14
+ value: value,
15
+ onChange: (e)=>{
16
+ setValue(e.target.value);
17
+ handleSave(e.target.value);
18
+ },
19
+ flex: props.w ? void 0 : 1,
20
+ rightSection: loading ? /*#__PURE__*/ jsx(Loader, {
21
+ size: "sm"
22
+ }) : void 0,
23
+ ...props
24
+ });
25
+ };
26
+ export { Textarea_Textarea as Textarea };
@@ -0,0 +1,2 @@
1
+ import { SaveInput } from "./SaveInput.js";
2
+ export { SaveInput };
@@ -0,0 +1,30 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ScrollAreaProvider } from "./context.js";
3
+ import { ScrollAreaButton } from "./ScrollAreaButton.js";
4
+ import { ScrollAreaContent } from "./ScrollAreaContent.js";
5
+ import { useScrollAreaState } from "./useScrollArea.js";
6
+ const ScrollAreaRoot = ({ children, autoScroll = false, scrollToBottomOnInit = false, animated = true, nearThreshold = 100, radius, ...mantineProps })=>{
7
+ const scrollAreaValue = useScrollAreaState({
8
+ autoScroll,
9
+ scrollToBottomOnInit,
10
+ animated,
11
+ nearThreshold
12
+ });
13
+ const contextValue = {
14
+ ...scrollAreaValue,
15
+ radius,
16
+ mantineProps
17
+ };
18
+ return /*#__PURE__*/ jsx(ScrollAreaProvider, {
19
+ value: contextValue,
20
+ children: /*#__PURE__*/ jsx(ScrollAreaContent, {
21
+ children: children
22
+ })
23
+ });
24
+ };
25
+ ScrollAreaRoot.displayName = 'ScrollArea';
26
+ const ScrollArea = Object.assign(ScrollAreaRoot, {
27
+ ScrollButton: ScrollAreaButton,
28
+ Provider: ScrollAreaProvider
29
+ });
30
+ export { ScrollArea };
@@ -0,0 +1,30 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ActionIcon } from "@mantine/core";
3
+ import { IconChevronDown, IconChevronUp } from "@tabler/icons-react";
4
+ import { useScrollArea } from "./context.js";
5
+ const ScrollAreaButton = ({ className, upIcon, downIcon })=>{
6
+ const { hasScrollableContent, isAboveCenter, scrollToTop, scrollToBottom } = useScrollArea();
7
+ if (!hasScrollableContent) return null;
8
+ const isScrollingDown = isAboveCenter;
9
+ const icon = isScrollingDown ? downIcon ?? /*#__PURE__*/ jsx(IconChevronDown, {
10
+ strokeWidth: 1.5
11
+ }) : upIcon ?? /*#__PURE__*/ jsx(IconChevronUp, {
12
+ strokeWidth: 1.5
13
+ });
14
+ const handleClick = ()=>{
15
+ if (isScrollingDown) scrollToBottom();
16
+ else scrollToTop();
17
+ };
18
+ return /*#__PURE__*/ jsx(ActionIcon, {
19
+ pos: "absolute",
20
+ bottom: 16,
21
+ right: 16,
22
+ variant: "light",
23
+ onClick: handleClick,
24
+ className: className,
25
+ "aria-label": isScrollingDown ? 'Scroll to bottom' : 'Scroll to top',
26
+ children: icon
27
+ });
28
+ };
29
+ ScrollAreaButton.displayName = 'ScrollArea.ScrollButton';
30
+ export { ScrollAreaButton };
@@ -0,0 +1,30 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Box, ScrollArea, getRadius } from "@mantine/core";
3
+ import { useContext } from "react";
4
+ import { ScrollAreaContext } from "./context.js";
5
+ import styles_module from "./styles.module.js";
6
+ const ScrollAreaContent = ({ children })=>{
7
+ const fullContext = useContext(ScrollAreaContext);
8
+ if (!fullContext) throw new Error('ScrollAreaContent must be used within ScrollArea');
9
+ const { _callbackRef, mantineProps, radius, _contentResizeRef } = fullContext;
10
+ return /*#__PURE__*/ jsx(ScrollArea, {
11
+ classNames: {
12
+ viewport: styles_module.viewport,
13
+ content: styles_module.content,
14
+ scrollbar: styles_module.scrollbar
15
+ },
16
+ style: {
17
+ '--radius': radius ? getRadius(radius) : void 0
18
+ },
19
+ ...mantineProps,
20
+ viewportRef: _callbackRef,
21
+ children: /*#__PURE__*/ jsx(Box, {
22
+ h: "100%",
23
+ w: "100%",
24
+ ref: _contentResizeRef,
25
+ children: children
26
+ })
27
+ });
28
+ };
29
+ ScrollAreaContent.displayName = 'ScrollArea.Content';
30
+ export { ScrollAreaContent };
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from "react";
2
+ const ScrollAreaContext = /*#__PURE__*/ createContext(null);
3
+ const ScrollAreaProvider = ScrollAreaContext.Provider;
4
+ const useScrollArea = ()=>{
5
+ const context = useContext(ScrollAreaContext);
6
+ if (!context) throw new Error('useScrollArea must be used within ScrollArea');
7
+ const { _callbackRef, mantineProps: _, radius: __, ...publicAPI } = context;
8
+ return publicAPI;
9
+ };
10
+ export { ScrollAreaContext, ScrollAreaProvider, useScrollArea };
@@ -0,0 +1,3 @@
1
+ import { useScrollArea } from "./context.js";
2
+ import { ScrollArea } from "./ScrollArea.js";
3
+ export { ScrollArea, useScrollArea };
@@ -0,0 +1,7 @@
1
+ import "./styles_module.css";
2
+ const styles_module = {
3
+ viewport: "viewport-KXLjEt",
4
+ content: "content-An6Wm1",
5
+ scrollbar: "scrollbar-q5GUTX"
6
+ };
7
+ export { styles_module as default };
@@ -0,0 +1,14 @@
1
+ .viewport-KXLjEt {
2
+ border-radius: var(--radius);
3
+ }
4
+
5
+ .content-An6Wm1 {
6
+ width: 100%;
7
+ height: 100%;
8
+ }
9
+
10
+ .scrollbar-q5GUTX {
11
+ border-top-right-radius: var(--radius);
12
+ border-bottom-right-radius: var(--radius);
13
+ }
14
+
File without changes
@@ -0,0 +1,146 @@
1
+ import { useDebouncedCallback, useMergedRef, useResizeObserver } from "@mantine/hooks";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ const useScrollAreaState = (options = {})=>{
4
+ const { autoScroll = false, scrollToBottomOnInit = false, animated = true, nearThreshold = 32 } = options;
5
+ const scrollAreaRef = useRef(null);
6
+ const isUserInteractingRef = useRef(false);
7
+ const userInteractionTimeoutRef = useRef(void 0);
8
+ const isInitializedRef = useRef(false);
9
+ const [contentResizeRef, contentRect] = useResizeObserver();
10
+ const [scrollPosition, setScrollPosition] = useState({
11
+ scrollTop: 0,
12
+ clientHeight: 0,
13
+ scrollHeight: 0
14
+ });
15
+ const isAtTop = 0 === scrollPosition.scrollTop;
16
+ const isAtBottom = scrollPosition.scrollTop + scrollPosition.clientHeight >= scrollPosition.scrollHeight;
17
+ const isNearTop = scrollPosition.scrollTop <= nearThreshold;
18
+ const isNearBottom = scrollPosition.scrollTop + scrollPosition.clientHeight >= scrollPosition.scrollHeight - nearThreshold;
19
+ const isAboveCenter = scrollPosition.scrollTop < (scrollPosition.scrollHeight - scrollPosition.clientHeight) / 2;
20
+ const hasScrollableContent = scrollPosition.scrollHeight > scrollPosition.clientHeight;
21
+ const debouncedUpdatePosition = useDebouncedCallback((element)=>{
22
+ const newPosition = {
23
+ scrollTop: element.scrollTop,
24
+ clientHeight: element.clientHeight,
25
+ scrollHeight: element.scrollHeight
26
+ };
27
+ setScrollPosition(newPosition);
28
+ }, {
29
+ delay: 16
30
+ });
31
+ const scrollToTop = useCallback((isAnimated)=>{
32
+ const element = scrollAreaRef.current;
33
+ if (!element) return;
34
+ const shouldAnimate = isAnimated ?? animated;
35
+ if (shouldAnimate) element.scrollTo({
36
+ top: 0,
37
+ behavior: 'smooth'
38
+ });
39
+ else element.scrollTop = 0;
40
+ }, [
41
+ animated
42
+ ]);
43
+ const scrollToBottom = useCallback((isAnimated)=>{
44
+ const element = scrollAreaRef.current;
45
+ if (!element) return;
46
+ const shouldAnimate = isAnimated ?? animated;
47
+ if (shouldAnimate) element.scrollTo({
48
+ top: element.scrollHeight,
49
+ behavior: 'smooth'
50
+ });
51
+ else element.scrollTop = element.scrollHeight;
52
+ const scrollHeightBefore = element.scrollHeight;
53
+ setTimeout(()=>{
54
+ const scrollHeightAfter = element.scrollHeight;
55
+ const diff = element.scrollHeight - (element.scrollTop + element.clientHeight);
56
+ if (diff > 1 && scrollHeightAfter !== scrollHeightBefore) element.scrollTop = element.scrollHeight;
57
+ }, 50);
58
+ }, [
59
+ animated
60
+ ]);
61
+ const performAutoScroll = useCallback(()=>{
62
+ if (!autoScroll || isUserInteractingRef.current || !scrollAreaRef.current) return;
63
+ if (isAtBottom) scrollToBottom(false);
64
+ }, [
65
+ autoScroll,
66
+ isAtBottom,
67
+ scrollToBottom
68
+ ]);
69
+ const handleUserInteraction = useCallback(()=>{
70
+ isUserInteractingRef.current = true;
71
+ if (userInteractionTimeoutRef.current) clearTimeout(userInteractionTimeoutRef.current);
72
+ userInteractionTimeoutRef.current = setTimeout(()=>{
73
+ isUserInteractingRef.current = false;
74
+ }, 150);
75
+ }, []);
76
+ const handleScroll = useCallback((event)=>{
77
+ const element = event.target;
78
+ debouncedUpdatePosition(element);
79
+ }, [
80
+ debouncedUpdatePosition
81
+ ]);
82
+ useEffect(()=>{
83
+ if (!scrollToBottomOnInit || isInitializedRef.current) return;
84
+ if (hasScrollableContent) {
85
+ scrollToBottom(animated);
86
+ isInitializedRef.current = true;
87
+ }
88
+ }, [
89
+ scrollToBottomOnInit,
90
+ hasScrollableContent,
91
+ scrollToBottom,
92
+ animated
93
+ ]);
94
+ useEffect(()=>{
95
+ const element = scrollAreaRef.current;
96
+ if (!element || 0 === contentRect.height) return;
97
+ debouncedUpdatePosition(element);
98
+ const timeoutId = setTimeout(performAutoScroll, 10);
99
+ return ()=>clearTimeout(timeoutId);
100
+ }, [
101
+ contentRect.height,
102
+ debouncedUpdatePosition,
103
+ performAutoScroll
104
+ ]);
105
+ useEffect(()=>{
106
+ const element = scrollAreaRef.current;
107
+ if (!element) return;
108
+ const events = [
109
+ 'wheel',
110
+ 'touchstart',
111
+ 'touchmove',
112
+ 'mousedown'
113
+ ];
114
+ element.addEventListener('scroll', handleScroll);
115
+ events.forEach((event)=>{
116
+ element.addEventListener(event, handleUserInteraction);
117
+ });
118
+ debouncedUpdatePosition(element);
119
+ return ()=>{
120
+ element.removeEventListener('scroll', handleScroll);
121
+ events.forEach((event)=>{
122
+ element.removeEventListener(event, handleUserInteraction);
123
+ });
124
+ if (userInteractionTimeoutRef.current) clearTimeout(userInteractionTimeoutRef.current);
125
+ };
126
+ }, [
127
+ handleScroll,
128
+ handleUserInteraction,
129
+ debouncedUpdatePosition
130
+ ]);
131
+ const callbackRef = useMergedRef(scrollAreaRef);
132
+ return {
133
+ isAtTop,
134
+ isNearTop,
135
+ isAtBottom,
136
+ isNearBottom,
137
+ isAboveCenter,
138
+ hasScrollableContent,
139
+ scrollToTop,
140
+ scrollToBottom,
141
+ viewportRef: scrollAreaRef,
142
+ _callbackRef: callbackRef,
143
+ _contentResizeRef: contentResizeRef
144
+ };
145
+ };
146
+ export { useScrollAreaState };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rolder/kit",
3
- "version": "3.0.0-alpha-10",
3
+ "version": "3.0.0-alpha-12",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {