@noya-app/noya-designsystem 0.1.77 → 0.1.78

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 (81) hide show
  1. package/.turbo/turbo-build.log +20 -12
  2. package/CHANGELOG.md +9 -0
  3. package/dist/chunk-D57E6H3M.mjs +36 -0
  4. package/dist/chunk-D57E6H3M.mjs.map +1 -0
  5. package/dist/emojis.d.mts +1 -0
  6. package/dist/emojis.d.ts +1 -0
  7. package/dist/emojis.js +31 -0
  8. package/dist/emojis.js.map +1 -0
  9. package/dist/emojis.mjs +8 -0
  10. package/dist/emojis.mjs.map +1 -0
  11. package/dist/index.css +1 -1
  12. package/dist/index.d.mts +142 -90
  13. package/dist/index.d.ts +142 -90
  14. package/dist/index.js +3171 -1745
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +3349 -1918
  17. package/dist/index.mjs.map +1 -1
  18. package/package.json +11 -7
  19. package/src/__tests__/__snapshots__/fuzzyScorer.test.ts.snap +1 -1
  20. package/src/components/Avatar.tsx +10 -10
  21. package/src/components/Banner.tsx +1 -1
  22. package/src/components/BaseToolbar.tsx +1 -1
  23. package/src/components/Button.tsx +2 -1
  24. package/src/components/Chip.tsx +1 -1
  25. package/src/components/ColorSwatchControl.tsx +22 -14
  26. package/src/components/CommandPalette.tsx +10 -6
  27. package/src/components/ContextMenu.tsx +249 -38
  28. package/src/components/Dialog.tsx +70 -67
  29. package/src/components/Drawer.tsx +56 -17
  30. package/src/components/DropdownMenu.tsx +305 -46
  31. package/src/components/EditableText.tsx +1 -1
  32. package/src/components/EmojiPicker.tsx +645 -0
  33. package/src/components/GridView.tsx +5 -1
  34. package/src/components/IVirtualizedList.tsx +21 -1
  35. package/src/components/InputField.tsx +2 -10
  36. package/src/components/InspectorContainer.tsx +4 -2
  37. package/src/components/Message.tsx +5 -16
  38. package/src/components/Popover.tsx +73 -107
  39. package/src/components/Progress.tsx +18 -18
  40. package/src/components/ScrollArea.tsx +66 -31
  41. package/src/components/ScrollableSidebar.tsx +1 -1
  42. package/src/components/SegmentedControl.tsx +166 -38
  43. package/src/components/SelectMenu.tsx +193 -101
  44. package/src/components/Slider.tsx +40 -38
  45. package/src/components/Switch.tsx +4 -4
  46. package/src/components/TextArea.tsx +1 -1
  47. package/src/components/Toast.tsx +99 -26
  48. package/src/components/Toolbar.tsx +114 -16
  49. package/src/components/Tooltip.tsx +18 -8
  50. package/src/components/Virtualized.tsx +193 -14
  51. package/src/components/VisuallyHidden.tsx +20 -0
  52. package/src/components/__tests__/Virtualized.math.test.ts +426 -1
  53. package/src/components/__tests__/Virtualized.test.tsx +129 -1
  54. package/src/components/ai-assistant/AIAssistantLayout.tsx +11 -6
  55. package/src/components/internal/Menu.tsx +4 -0
  56. package/src/components/listView/ListViewEditableRowTitle.tsx +1 -1
  57. package/src/components/listView/ListViewRoot.tsx +5 -1
  58. package/src/components/resizablePanels/Panel.tsx +94 -0
  59. package/src/components/resizablePanels/PanelGroup.tsx +498 -0
  60. package/src/components/resizablePanels/PanelGroupContext.tsx +14 -0
  61. package/src/components/resizablePanels/PanelResizeHandle.tsx +61 -0
  62. package/src/components/resizablePanels/index.ts +7 -0
  63. package/src/components/resizablePanels/types.ts +65 -0
  64. package/src/components/workspace/DrawerWorkspaceLayout.tsx +22 -7
  65. package/src/components/workspace/PanelWorkspaceLayout.tsx +30 -84
  66. package/src/components/workspace/WorkspaceLayout.tsx +28 -58
  67. package/src/components/workspace/types.ts +6 -4
  68. package/src/contexts/DialogContext.tsx +15 -24
  69. package/src/emojis.ts +1 -0
  70. package/src/hooks/useTriggerToggle.ts +95 -0
  71. package/src/index.css +2 -0
  72. package/src/index.tsx +1 -2
  73. package/src/theme/proseTheme.ts +2 -0
  74. package/src/utils/mergeProps.ts +57 -0
  75. package/src/utils/skinTone.ts +90 -0
  76. package/tsup.config.ts +1 -1
  77. package/src/__tests__/workspaceLayout.test.ts +0 -281
  78. package/src/components/ScrollArea2.tsx +0 -76
  79. package/src/components/internal/MenuViewport.tsx +0 -178
  80. package/src/components/internal/SelectItem.tsx +0 -138
  81. package/src/components/workspace/panelStorage.ts +0 -216
@@ -42,7 +42,7 @@ export const InspectorContainer = memo(
42
42
  >
43
43
  {header}
44
44
  {children ? (
45
- <ScrollArea>
45
+ <ScrollArea className="n-flex-1 n-min-h-0">
46
46
  <div className="n-flex n-flex-col n-relative">
47
47
  {showDividers
48
48
  ? withSeparatorElements(children, <Divider />)
@@ -50,7 +50,9 @@ export const InspectorContainer = memo(
50
50
  </div>
51
51
  </ScrollArea>
52
52
  ) : fallback ? (
53
- <div className="n-flex n-flex-col n-relative n-h-full">{fallback}</div>
53
+ <div className="n-flex n-flex-col n-relative n-h-full">
54
+ {fallback}
55
+ </div>
54
56
  ) : null}
55
57
  </div>
56
58
  );
@@ -5,7 +5,6 @@ import { uuid } from "@noya-app/noya-utils";
5
5
  import React, { forwardRef, memo, useMemo } from "react";
6
6
  import { cssVars, INPUT_HEIGHT } from "../theme";
7
7
  import { cx } from "../utils/classNames";
8
- import { colorFromString } from "../utils/colorFromString";
9
8
  import { Avatar } from "./Avatar";
10
9
  import { Logo } from "./NoyaLogo";
11
10
 
@@ -22,18 +21,8 @@ export const Message = memo(
22
21
  { role, children, user, avatarSize = INPUT_HEIGHT }: MessageProps,
23
22
  ref: React.ForwardedRef<HTMLDivElement>
24
23
  ) {
25
- const randomId = uuid();
24
+ const randomId = useMemo(() => uuid(), []);
26
25
  const resolvedUserId = user?.authId ?? user?.connectionId ?? randomId;
27
- const userMessageBackgroundColor = colorFromString(resolvedUserId);
28
- const styles = useMemo(
29
- () =>
30
- role === "user"
31
- ? {
32
- backgroundColor: userMessageBackgroundColor,
33
- }
34
- : undefined,
35
- [userMessageBackgroundColor, role]
36
- );
37
26
  return (
38
27
  <div
39
28
  className={cx(
@@ -60,11 +49,11 @@ export const Message = memo(
60
49
  <div
61
50
  className={cx(
62
51
  "markdown-message",
63
- "n-flex n-flex-row n-gap-2 n-rounded-lg n-py-2 n-px-3 n-transition-all n-duration-200 n-max-w-[70%] n-text-sm",
64
- role === "user" ? "n-text-white" : "n-text-text",
65
- role === "user" ? "n-ml-auto" : "n-bg-input-background"
52
+ "n-rounded-lg n-py-2 n-px-3 n-transition-all n-duration-200 n-max-w-[70%] n-min-w-0 n-text-sm [&_pre]:n-whitespace-pre-wrap [&_code]:n-whitespace-pre-wrap",
53
+ role === "user"
54
+ ? "n-text-white n-ml-auto n-bg-primary"
55
+ : "n-text-text n-bg-input-background"
66
56
  )}
67
- style={styles}
68
57
  ref={ref}
69
58
  >
70
59
  {children}
@@ -1,39 +1,21 @@
1
1
  "use client";
2
2
 
3
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
3
4
  import { useControlledOrUncontrolled } from "@noya-app/react-utils";
4
- import { Popover as PopoverPrimitive } from "radix-ui";
5
- import React, {
6
- ComponentProps,
7
- useCallback,
8
- useEffect,
9
- useId,
10
- useRef,
11
- } from "react";
5
+ import React, { useCallback, useEffect, useId } from "react";
12
6
  import { useOpenPortalsControls } from "../contexts/OpenPortalsContext";
13
7
  import {
14
8
  portalScopeProps,
15
9
  usePortalScopeId,
16
10
  } from "../contexts/PortalScopeContext";
11
+ import { useTriggerToggle } from "../hooks/useTriggerToggle";
17
12
  import { cx } from "../utils/classNames";
13
+ import { mergePropsWithEventComposition } from "../utils/mergeProps";
18
14
  import { IconButton } from "./IconButton";
19
15
 
20
- const closeStyles: React.CSSProperties = {
21
- all: "unset",
22
- fontFamily: "inherit",
23
- };
24
-
25
16
  type PopoverVariant = "normal" | "large";
26
17
 
27
- interface Props
28
- extends Pick<
29
- ComponentProps<(typeof PopoverPrimitive)["Content"]>,
30
- | "onOpenAutoFocus"
31
- | "onCloseAutoFocus"
32
- | "onPointerDownOutside"
33
- | "onInteractOutside"
34
- | "onFocusOutside"
35
- | "side"
36
- > {
18
+ interface Props {
37
19
  children:
38
20
  | React.ReactNode
39
21
  | ((props: { close: () => void }) => React.ReactNode);
@@ -48,11 +30,16 @@ interface Props
48
30
  className?: string;
49
31
  style?: React.CSSProperties;
50
32
  portalContainer?: HTMLElement | null;
33
+ side?: "top" | "bottom" | "left" | "right";
34
+ /**
35
+ * Called when an interaction outside the popover occurs.
36
+ * Return false to prevent the popover from closing.
37
+ */
38
+ shouldCloseOnInteractOutside?: (event: PointerEvent) => boolean;
51
39
  }
52
40
 
53
41
  export const popoverStyle = {
54
- base:
55
- "n-rounded n-font-[14px] n-bg-popover-background n-shadow-popover n-max-h-[600px] n-overflow-y-auto n-text-text-muted n-z-[1000]",
42
+ base: "n-rounded n-font-[14px] n-bg-popover-background n-shadow-popover n-max-h-[600px] n-overflow-y-auto n-text-text-muted n-z-[1000]",
56
43
  large: "n-w-[680px]",
57
44
  normal: "n-w-[240px]",
58
45
  };
@@ -67,19 +54,14 @@ export function Popover({
67
54
  sideOffset = 4,
68
55
  showArrow = true,
69
56
  onOpenChange,
70
- onOpenAutoFocus,
71
- onCloseAutoFocus,
72
- onPointerDownOutside,
73
- onInteractOutside,
74
- onFocusOutside,
75
57
  onClickClose,
76
58
  className,
77
59
  portalContainer,
78
60
  style,
61
+ shouldCloseOnInteractOutside,
79
62
  }: Props) {
80
63
  const defaultId = useId();
81
64
  const portalScopeId = usePortalScopeId();
82
- const contentRef = useRef<HTMLDivElement>(null);
83
65
  const [isOpen, setIsOpen] = useControlledOrUncontrolled({
84
66
  value: open,
85
67
  onChange: onOpenChange,
@@ -87,6 +69,9 @@ export function Popover({
87
69
  });
88
70
  const close = useCallback(() => setIsOpen(false), [setIsOpen]);
89
71
 
72
+ const { anchorElement, setAnchorElement, popupRef, handleOpenChange } =
73
+ useTriggerToggle(isOpen, setIsOpen, { shouldCloseOnInteractOutside });
74
+
90
75
  const { addOpenPortal, removeOpenPortal } = useOpenPortalsControls();
91
76
 
92
77
  useEffect(() => {
@@ -100,91 +85,72 @@ export function Popover({
100
85
  }, [addOpenPortal, isOpen, portalScopeId, removeOpenPortal, defaultId]);
101
86
 
102
87
  return (
103
- <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>
104
- <PopoverPrimitive.Trigger asChild>{trigger}</PopoverPrimitive.Trigger>
88
+ <PopoverPrimitive.Root open={isOpen} onOpenChange={handleOpenChange}>
89
+ <PopoverPrimitive.Trigger
90
+ render={(triggerProps) => {
91
+ const element = React.isValidElement(trigger) ? (
92
+ trigger
93
+ ) : (
94
+ <span>{trigger}</span>
95
+ );
96
+ const childProps = element.props as Record<string, unknown>;
97
+ const mergedProps = mergePropsWithEventComposition(
98
+ triggerProps as Record<string, unknown>,
99
+ childProps
100
+ );
101
+
102
+ // Custom ref handling for anchor tracking
103
+ mergedProps.ref = (node: Element | null) => {
104
+ // Only update state when we get a valid node to prevent anchor loss during rerenders
105
+ if (node) setAnchorElement(node);
106
+ };
107
+
108
+ return React.cloneElement(
109
+ element as React.ReactElement<any>,
110
+ mergedProps
111
+ );
112
+ }}
113
+ />
105
114
  <PopoverPrimitive.Portal container={portalContainer}>
106
- <PopoverPrimitive.Content
115
+ <PopoverPrimitive.Positioner
107
116
  {...portalScopeProps(portalScopeId)}
108
- ref={contentRef}
109
- style={style}
110
- className={cx(
111
- popoverStyle.base,
112
- variant === "large" && popoverStyle.large,
113
- variant === "normal" && popoverStyle.normal,
114
- className
115
- )}
117
+ anchor={anchorElement}
116
118
  side={side}
117
119
  align="center"
118
120
  sideOffset={sideOffset}
119
- onOpenAutoFocus={onOpenAutoFocus}
120
- onCloseAutoFocus={onCloseAutoFocus}
121
- onInteractOutside={onInteractOutside}
122
- onFocusOutside={onFocusOutside}
123
- onPointerDownOutside={(event) => {
124
- if (
125
- isEventInsideElement(
126
- event.detail.originalEvent,
127
- contentRef.current
128
- )
129
- ) {
130
- event.preventDefault();
131
- }
132
-
133
- onPointerDownOutside?.(event);
134
- }}
135
121
  collisionPadding={8}
136
122
  arrowPadding={2}
137
- // Don't propagate pointer down events to the canvas
138
- // onPointerDown={(event) => {
139
- // event.stopPropagation();
140
- // }}
141
- // onWheel={(event) => {
142
- // event.stopPropagation();
143
- // }}
123
+ className="n-z-menu"
144
124
  >
145
- {typeof children === "function" ? children({ close }) : children}
146
- {showArrow && (
147
- <PopoverPrimitive.Arrow className="n-fill-popover-background" />
148
- )}
149
- {closable && (
150
- <PopoverPrimitive.Close
151
- className="n-rounded-full n-h-[25px] n-w-[25px] n-inline-flex n-items-center n-justify-center n-absolute n-top-[5px] n-right-[5px]"
152
- style={closeStyles}
153
- >
154
- <IconButton iconName="Cross2Icon" onClick={onClickClose} />
155
- </PopoverPrimitive.Close>
156
- )}
157
- </PopoverPrimitive.Content>
125
+ <PopoverPrimitive.Popup
126
+ ref={popupRef}
127
+ style={style}
128
+ className={cx(
129
+ popoverStyle.base,
130
+ variant === "large" && popoverStyle.large,
131
+ variant === "normal" && popoverStyle.normal,
132
+ className
133
+ )}
134
+ >
135
+ {typeof children === "function" ? children({ close }) : children}
136
+ {showArrow && (
137
+ <PopoverPrimitive.Arrow className="n-fill-popover-background" />
138
+ )}
139
+ {closable && (
140
+ <PopoverPrimitive.Close
141
+ className="n-rounded-full n-h-[25px] n-w-[25px] n-inline-flex n-items-center n-justify-center n-absolute n-top-[5px] n-right-[5px]"
142
+ render={
143
+ <IconButton
144
+ iconName="Cross2Icon"
145
+ onClick={onClickClose}
146
+ style={{ all: "unset", fontFamily: "inherit" }}
147
+ />
148
+ }
149
+ />
150
+ )}
151
+ </PopoverPrimitive.Popup>
152
+ </PopoverPrimitive.Positioner>
158
153
  </PopoverPrimitive.Portal>
159
154
  </PopoverPrimitive.Root>
160
155
  );
161
156
  }
162
-
163
- /**
164
- * Radix ignores pointer-events on the body when a popover is open.
165
- * This function checks if an event is inside an element by temporarily
166
- * setting pointer-events to auto and then restoring it afterward.
167
- */
168
- function isEventInsideElement(
169
- event: PointerEvent,
170
- element: HTMLElement | null
171
- ) {
172
- if (!element) return false;
173
-
174
- const body = document.body;
175
- const originalPointerEvents = body.style.pointerEvents;
176
- body.style.pointerEvents = "auto";
177
-
178
- // Get all elements at the point
179
- const elementsAtPoint = document.elementsFromPoint(
180
- event.clientX,
181
- event.clientY
182
- );
183
-
184
- // Restore original pointer-events
185
- body.style.pointerEvents = originalPointerEvents;
186
-
187
- const target = elementsAtPoint.at(0);
188
-
189
- return target && element.contains(target);
190
- }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { clamp } from "@noya-app/noya-utils";
4
- import { Progress as ProgressPrimitive } from "radix-ui";
4
+ import { Progress as ProgressPrimitive } from "@base-ui/react/progress";
5
5
  import * as React from "react";
6
6
  import { cx } from "../utils/classNames";
7
7
 
@@ -23,19 +23,17 @@ export function Progress({
23
23
  style?: React.CSSProperties;
24
24
  }) {
25
25
  const clampedValue = clamp(value, 0, 100);
26
- const transformStyles = React.useMemo(
27
- () => ({
28
- transform: `translateX(-${100 - clampedValue}%)`,
29
- backgroundColor: color,
30
- }),
31
- [color, clampedValue]
32
- );
33
26
 
34
27
  const style = React.useMemo(
35
28
  () => ({ transform: "translateZ(0)", ...styleProp }),
36
29
  [styleProp]
37
30
  );
38
31
 
32
+ const indicatorStyle = React.useMemo(
33
+ () => ({ backgroundColor: color }),
34
+ [color]
35
+ );
36
+
39
37
  return (
40
38
  <ProgressPrimitive.Root
41
39
  className={cx(
@@ -45,16 +43,18 @@ export function Progress({
45
43
  style={style}
46
44
  value={clampedValue}
47
45
  >
48
- <ProgressPrimitive.Indicator
49
- className={cx(
50
- "n-transition-[transform_660ms_cubic-bezier(0.65,0,0.35,1)] n-w-full n-h-full",
51
- colorScheme === "primary" && "n-bg-primary",
52
- colorScheme === "secondary" && "n-bg-secondary",
53
- colorScheme === "warning" && "n-bg-warning",
54
- colorScheme === "normal" && "n-bg-text"
55
- )}
56
- style={transformStyles}
57
- />
46
+ <ProgressPrimitive.Track className="n-w-full n-h-full">
47
+ <ProgressPrimitive.Indicator
48
+ className={cx(
49
+ "n-transition-[width_660ms_cubic-bezier(0.65,0,0.35,1)] n-h-full",
50
+ colorScheme === "primary" && "n-bg-primary",
51
+ colorScheme === "secondary" && "n-bg-secondary",
52
+ colorScheme === "warning" && "n-bg-warning",
53
+ colorScheme === "normal" && "n-bg-text"
54
+ )}
55
+ style={indicatorStyle}
56
+ />
57
+ </ProgressPrimitive.Track>
58
58
  </ProgressPrimitive.Root>
59
59
  );
60
60
  }
@@ -1,41 +1,76 @@
1
1
  "use client";
2
2
 
3
- import { ScrollArea as RadixScrollArea } from "radix-ui";
3
+ import { ScrollArea as BScrollArea } from "@base-ui/react/scroll-area";
4
4
  import * as React from "react";
5
+ import { cx } from "../utils/classNames";
5
6
 
6
- interface Props {
7
- children?:
8
- | React.ReactNode
9
- | ((scrollElementRef: HTMLDivElement) => React.ReactNode);
10
- }
7
+ const SCROLLBAR_STATE_CLASSES =
8
+ "scroll-component n-opacity-0 n-transition-opacity n-delay-300 n-pointer-events-none data-[hovering]:n-opacity-100 data-[hovering]:n-delay-0 data-[hovering]:n-duration-75 data-[hovering]:n-pointer-events-auto data-[scrolling]:n-opacity-100 data-[scrolling]:n-delay-0 data-[scrolling]:n-duration-75 data-[scrolling]:n-pointer-events-auto";
9
+
10
+ const SCROLLBAR_TRACK_VERTICAL =
11
+ "n-m-1 n-w-1 flex n-justify-center n-rounded-md n-bg-divider-subtle";
12
+ const SCROLLBAR_TRACK_HORIZONTAL =
13
+ "n-m-1 n-h-1 flex n-justify-center n-rounded-md n-bg-divider-subtle";
14
+
15
+ const SCROLLBAR_THUMB_VERTICAL =
16
+ "scroll-component n-w-full n-rounded n-bg-scrollbar";
17
+ const SCROLLBAR_THUMB_HORIZONTAL =
18
+ "scroll-component n-h-full n-rounded n-bg-scrollbar";
11
19
 
12
- export const ScrollArea = React.memo(function ScrollArea({ children }: Props) {
13
- const [scrollElementRef, setScrollElementRef] =
14
- React.useState<HTMLDivElement | null>(null);
20
+ type ScrollAreaViewportProps = React.HTMLAttributes<HTMLDivElement> & {
21
+ ref?: React.Ref<HTMLDivElement>;
22
+ };
23
+
24
+ export function ScrollArea({
25
+ children,
26
+ className,
27
+ viewportClassName,
28
+ orientation = "vertical",
29
+ style,
30
+ viewportProps,
31
+ }: {
32
+ children: React.ReactNode;
33
+ className?: string;
34
+ viewportClassName?: string;
35
+ orientation?: "vertical" | "horizontal" | "both";
36
+ style?: React.CSSProperties;
37
+ viewportProps?: ScrollAreaViewportProps;
38
+ }) {
39
+ const {
40
+ className: viewportPropsClassName,
41
+ ref: viewportRef,
42
+ ...viewportRest
43
+ } = viewportProps ?? {};
15
44
 
16
45
  return (
17
- <div className="n-flex-1 n-min-h-0">
18
- <RadixScrollArea.Root style={{ width: "100%", height: "100%" }}>
19
- <RadixScrollArea.Viewport
20
- className="n-w-full n-h-full [&>div]:n-block"
21
- ref={React.useCallback(
22
- (ref: HTMLDivElement | null) => setScrollElementRef(ref),
23
- []
24
- )}
46
+ <BScrollArea.Root className={cx("n-relative", className)} style={style}>
47
+ <BScrollArea.Viewport
48
+ ref={viewportRef}
49
+ className={cx(
50
+ "n-h-full n-overscroll-contain",
51
+ viewportClassName,
52
+ viewportPropsClassName
53
+ )}
54
+ {...viewportRest}
55
+ >
56
+ {children}
57
+ </BScrollArea.Viewport>
58
+ {(orientation === "vertical" || orientation === "both") && (
59
+ <BScrollArea.Scrollbar
60
+ className={cx(SCROLLBAR_STATE_CLASSES, SCROLLBAR_TRACK_VERTICAL)}
25
61
  >
26
- {typeof children === "function"
27
- ? scrollElementRef
28
- ? children(scrollElementRef)
29
- : null
30
- : children}
31
- </RadixScrollArea.Viewport>
32
- <RadixScrollArea.Scrollbar
33
- orientation="vertical"
34
- className="n-scroll-component n-flex n-p-[3px] data-[orientation=vertical]:n-w-[10px]"
62
+ <BScrollArea.Thumb className={SCROLLBAR_THUMB_VERTICAL} />
63
+ </BScrollArea.Scrollbar>
64
+ )}
65
+ {(orientation === "horizontal" || orientation === "both") && (
66
+ <BScrollArea.Scrollbar
67
+ orientation="horizontal"
68
+ className={cx(SCROLLBAR_STATE_CLASSES, SCROLLBAR_TRACK_HORIZONTAL)}
35
69
  >
36
- <RadixScrollArea.Thumb className="n-scroll-component n-flex-1 n-rounded-[10px] n-bg-scrollbar" />
37
- </RadixScrollArea.Scrollbar>
38
- </RadixScrollArea.Root>
39
- </div>
70
+ <BScrollArea.Thumb className={SCROLLBAR_THUMB_HORIZONTAL} />
71
+ </BScrollArea.Scrollbar>
72
+ )}
73
+ {orientation === "both" && <BScrollArea.Corner />}
74
+ </BScrollArea.Root>
40
75
  );
41
- });
76
+ }
@@ -4,7 +4,7 @@ import { ScrollArea } from "./ScrollArea";
4
4
  export function ScrollableSidebar({ children }: { children: React.ReactNode }) {
5
5
  return (
6
6
  <div className="n-relative n-flex n-flex-col n-flex-1 n-max-h-full">
7
- <ScrollArea>{children}</ScrollArea>
7
+ <ScrollArea className="n-flex-1 n-min-h-0">{children}</ScrollArea>
8
8
  </div>
9
9
  );
10
10
  }