@noya-app/noya-designsystem 0.1.52 → 0.1.54
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.
- package/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +14 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +38 -12
- package/dist/index.d.ts +38 -12
- package/dist/index.js +421 -326
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +900 -814
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/components/Button.tsx +1 -1
- package/src/components/ColorSwatch.tsx +5 -2
- package/src/components/ColorSwatchControl.tsx +4 -6
- package/src/components/ContextMenu.tsx +10 -2
- package/src/components/DraggableMenuButton.tsx +17 -30
- package/src/components/DropdownMenu.tsx +7 -0
- package/src/components/Popover.tsx +7 -0
- package/src/components/SegmentedControl.tsx +13 -42
- package/src/components/SelectMenu.tsx +7 -0
- package/src/components/SelectionToolbar.tsx +51 -45
- package/src/components/Slider.tsx +1 -1
- package/src/components/Toolbar.tsx +124 -76
- package/src/components/Tooltip.tsx +7 -0
- package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +2 -2
- package/src/components/internal/Menu.tsx +2 -2
- package/src/components/internal/MenuViewport.tsx +9 -1
- package/src/components/internal/SelectItem.tsx +24 -3
- package/src/contexts/PortalScopeContext.tsx +48 -0
- package/src/index.tsx +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noya-app/noya-designsystem",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.54",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@dnd-kit/core": "6.3.1",
|
|
24
24
|
"@dnd-kit/sortable": "10.0.0",
|
|
25
|
-
"@noya-app/noya-colorpicker": "0.1.
|
|
25
|
+
"@noya-app/noya-colorpicker": "0.1.21",
|
|
26
26
|
"@noya-app/noya-utils": "0.1.5",
|
|
27
27
|
"@noya-app/noya-geometry": "0.1.11",
|
|
28
28
|
"@noya-app/noya-icons": "0.1.8",
|
|
@@ -89,7 +89,7 @@ export const Button = forwardRef(function Button(
|
|
|
89
89
|
disabled ? "opacity-25" : "",
|
|
90
90
|
!className?.includes("flex") ? "flex-none" : "",
|
|
91
91
|
active
|
|
92
|
-
? "bg-primary text-
|
|
92
|
+
? "bg-primary-pastel text-primary hover:bg-primary-pastel-light min-w-[31px]"
|
|
93
93
|
: variantStyles[variant],
|
|
94
94
|
sizeStyles[
|
|
95
95
|
variant === "thin"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef } from "react";
|
|
2
|
+
import { cssVars } from "../theme";
|
|
2
3
|
|
|
3
4
|
export type ColorSwatchSize = "xsmall" | "small" | "medium" | "large";
|
|
4
5
|
|
|
@@ -31,10 +32,12 @@ export const ColorSwatch = forwardRef(function ColorSwatch(
|
|
|
31
32
|
height: sizePx,
|
|
32
33
|
borderRadius: "4px",
|
|
33
34
|
outline: checked
|
|
34
|
-
?
|
|
35
|
+
? `2px solid ${cssVars.colors.primary}`
|
|
35
36
|
: "1px solid rgba(0,0,0,0.1)",
|
|
36
37
|
outlineOffset: -1,
|
|
37
|
-
boxShadow: checked
|
|
38
|
+
boxShadow: checked
|
|
39
|
+
? `inset 0 0 0 2px ${cssVars.colors.background}`
|
|
40
|
+
: undefined,
|
|
38
41
|
...style,
|
|
39
42
|
}}
|
|
40
43
|
/>
|
|
@@ -63,13 +63,12 @@ export function ColorSwatchControl(props: ColorSwatchControlProps) {
|
|
|
63
63
|
checked={value === option}
|
|
64
64
|
/>
|
|
65
65
|
);
|
|
66
|
-
return
|
|
67
|
-
item
|
|
68
|
-
) : (
|
|
66
|
+
return (
|
|
69
67
|
<ToggleGroupPrimitive.Item
|
|
70
68
|
asChild
|
|
71
69
|
value={option as string}
|
|
72
70
|
key={option as string}
|
|
71
|
+
disabled={readOnly}
|
|
73
72
|
>
|
|
74
73
|
{item}
|
|
75
74
|
</ToggleGroupPrimitive.Item>
|
|
@@ -77,14 +76,13 @@ export function ColorSwatchControl(props: ColorSwatchControlProps) {
|
|
|
77
76
|
})}
|
|
78
77
|
</div>
|
|
79
78
|
);
|
|
80
|
-
return
|
|
81
|
-
content
|
|
82
|
-
) : (
|
|
79
|
+
return (
|
|
83
80
|
<ToggleGroupPrimitive.Root
|
|
84
81
|
type="single"
|
|
85
82
|
value={value as string}
|
|
86
83
|
onValueChange={onValueChange}
|
|
87
84
|
className="w-full"
|
|
85
|
+
disabled={readOnly}
|
|
88
86
|
>
|
|
89
87
|
{content}
|
|
90
88
|
</ToggleGroupPrimitive.Root>
|
|
@@ -2,13 +2,16 @@ import { useKeyboardShortcuts } from "@noya-app/noya-keymap";
|
|
|
2
2
|
import { memoGeneric } from "@noya-app/react-utils";
|
|
3
3
|
import * as RadixContextMenu from "@radix-ui/react-context-menu";
|
|
4
4
|
import React, { ReactNode, useCallback, useMemo } from "react";
|
|
5
|
+
import {
|
|
6
|
+
portalScopeProps,
|
|
7
|
+
usePortalScopeId,
|
|
8
|
+
} from "../contexts/PortalScopeContext";
|
|
5
9
|
import {
|
|
6
10
|
MenuItem,
|
|
7
11
|
getKeyboardShortcutsForMenuItems,
|
|
8
12
|
styles,
|
|
9
13
|
} from "./internal/Menu";
|
|
10
14
|
import { MenuViewport } from "./internal/MenuViewport";
|
|
11
|
-
|
|
12
15
|
export interface MenuItemProps<T extends string> {
|
|
13
16
|
value?: T;
|
|
14
17
|
children: ReactNode;
|
|
@@ -60,6 +63,8 @@ function ContextMenuRoot<T extends string>({
|
|
|
60
63
|
[items, onSelect, shouldBindKeyboardShortcuts]
|
|
61
64
|
);
|
|
62
65
|
|
|
66
|
+
const portalScopeId = usePortalScopeId();
|
|
67
|
+
|
|
63
68
|
useKeyboardShortcuts(keymap);
|
|
64
69
|
|
|
65
70
|
// We call preventDefault both to:
|
|
@@ -85,7 +90,10 @@ function ContextMenuRoot<T extends string>({
|
|
|
85
90
|
{children}
|
|
86
91
|
</RadixContextMenu.Trigger>
|
|
87
92
|
<RadixContextMenu.Portal>
|
|
88
|
-
<RadixContextMenu.Content
|
|
93
|
+
<RadixContextMenu.Content
|
|
94
|
+
{...portalScopeProps(portalScopeId)}
|
|
95
|
+
className={styles.contentStyle}
|
|
96
|
+
>
|
|
89
97
|
<MenuViewport
|
|
90
98
|
items={items}
|
|
91
99
|
Components={Components}
|
|
@@ -1,36 +1,11 @@
|
|
|
1
1
|
import { DragHandleDots2Icon } from "@noya-app/noya-icons";
|
|
2
2
|
import { memoGeneric } from "@noya-app/react-utils";
|
|
3
|
-
import React, {
|
|
3
|
+
import React, { useCallback, useState } from "react";
|
|
4
4
|
import { cssVars } from "../theme";
|
|
5
5
|
import { cx } from "../utils/classNames";
|
|
6
6
|
import { DropdownMenu } from "./DropdownMenu";
|
|
7
7
|
import { MenuItem } from "./internal/Menu";
|
|
8
8
|
|
|
9
|
-
const DotButton = forwardRef<
|
|
10
|
-
HTMLDivElement,
|
|
11
|
-
React.HTMLAttributes<HTMLDivElement>
|
|
12
|
-
>(({ className, ...props }, ref) => (
|
|
13
|
-
<div
|
|
14
|
-
ref={ref}
|
|
15
|
-
className={cx(
|
|
16
|
-
`cursor-pointer rounded flex items-center justify-center py-[2px] hover:bg-input-background-light active:bg-active-background `,
|
|
17
|
-
className
|
|
18
|
-
)}
|
|
19
|
-
{...props}
|
|
20
|
-
/>
|
|
21
|
-
));
|
|
22
|
-
|
|
23
|
-
const Trigger = forwardRef<
|
|
24
|
-
HTMLDivElement,
|
|
25
|
-
React.HTMLAttributes<HTMLDivElement>
|
|
26
|
-
>(({ className, ...props }, ref) => (
|
|
27
|
-
<div
|
|
28
|
-
ref={ref}
|
|
29
|
-
className={cx(`pointer-events-none h-[15px] `, className)}
|
|
30
|
-
{...props}
|
|
31
|
-
/>
|
|
32
|
-
));
|
|
33
|
-
|
|
34
9
|
/**
|
|
35
10
|
* A button that opens a menu when clicked, but also allows dragging the
|
|
36
11
|
*/
|
|
@@ -39,11 +14,17 @@ export const DraggableMenuButton = memoGeneric(function DraggableMenuButton<
|
|
|
39
14
|
>({
|
|
40
15
|
items,
|
|
41
16
|
onSelect,
|
|
17
|
+
onClick,
|
|
42
18
|
isVisible = true,
|
|
19
|
+
className,
|
|
20
|
+
style,
|
|
43
21
|
}: {
|
|
44
22
|
items?: MenuItem<T>[];
|
|
45
23
|
onSelect?: (value: T) => void;
|
|
24
|
+
onClick?: () => void;
|
|
46
25
|
isVisible?: boolean;
|
|
26
|
+
className?: string;
|
|
27
|
+
style?: React.CSSProperties;
|
|
47
28
|
}) {
|
|
48
29
|
const [open, setOpen] = useState(false);
|
|
49
30
|
const [downPosition, setDownPosition] = useState<{
|
|
@@ -94,12 +75,18 @@ export const DraggableMenuButton = memoGeneric(function DraggableMenuButton<
|
|
|
94
75
|
);
|
|
95
76
|
|
|
96
77
|
return (
|
|
97
|
-
<
|
|
78
|
+
<div
|
|
79
|
+
className={cx(
|
|
80
|
+
"cursor-pointer rounded flex items-center justify-center py-[2px] hover:bg-input-background-light active:bg-active-background ",
|
|
81
|
+
className
|
|
82
|
+
)}
|
|
83
|
+
style={style}
|
|
98
84
|
onPointerDownCapture={handlePointerDownCapture}
|
|
99
85
|
onPointerUp={handlePointerUp}
|
|
100
86
|
onClick={(event) => {
|
|
101
87
|
event.stopPropagation();
|
|
102
88
|
event.preventDefault();
|
|
89
|
+
onClick?.();
|
|
103
90
|
}}
|
|
104
91
|
>
|
|
105
92
|
{items && onSelect ? (
|
|
@@ -110,17 +97,17 @@ export const DraggableMenuButton = memoGeneric(function DraggableMenuButton<
|
|
|
110
97
|
onSelect={onSelect}
|
|
111
98
|
shouldBindKeyboardShortcuts={false}
|
|
112
99
|
>
|
|
113
|
-
<
|
|
100
|
+
<div className="pointer-events-none h-[15px]">
|
|
114
101
|
<DragHandleDots2Icon
|
|
115
102
|
color={isVisible || open ? cssVars.colors.icon : "transparent"}
|
|
116
103
|
/>
|
|
117
|
-
</
|
|
104
|
+
</div>
|
|
118
105
|
</DropdownMenu>
|
|
119
106
|
) : (
|
|
120
107
|
<DragHandleDots2Icon
|
|
121
108
|
color={isVisible || open ? cssVars.colors.icon : "transparent"}
|
|
122
109
|
/>
|
|
123
110
|
)}
|
|
124
|
-
</
|
|
111
|
+
</div>
|
|
125
112
|
);
|
|
126
113
|
});
|
|
@@ -7,6 +7,10 @@ import React, {
|
|
|
7
7
|
SyntheticEvent,
|
|
8
8
|
useMemo,
|
|
9
9
|
} from "react";
|
|
10
|
+
import {
|
|
11
|
+
portalScopeProps,
|
|
12
|
+
usePortalScopeId,
|
|
13
|
+
} from "../contexts/PortalScopeContext";
|
|
10
14
|
import { MenuProps } from "./ContextMenu";
|
|
11
15
|
import { getKeyboardShortcutsForMenuItems, styles } from "./internal/Menu";
|
|
12
16
|
import { MenuViewport } from "./internal/MenuViewport";
|
|
@@ -57,6 +61,8 @@ const DropdownMenuRoot = forwardRefGeneric(function DropdownMenuRoot<
|
|
|
57
61
|
contentStyle,
|
|
58
62
|
} = props;
|
|
59
63
|
|
|
64
|
+
const portalScopeId = usePortalScopeId();
|
|
65
|
+
|
|
60
66
|
const keymap = useMemo(
|
|
61
67
|
() =>
|
|
62
68
|
shouldBindKeyboardShortcuts === false
|
|
@@ -86,6 +92,7 @@ const DropdownMenuRoot = forwardRefGeneric(function DropdownMenuRoot<
|
|
|
86
92
|
</RadixDropdownMenu.Trigger>
|
|
87
93
|
<RadixDropdownMenu.Portal>
|
|
88
94
|
<RadixDropdownMenu.Content
|
|
95
|
+
{...portalScopeProps(portalScopeId)}
|
|
89
96
|
className={styles.contentStyle}
|
|
90
97
|
side={side}
|
|
91
98
|
sideOffset={sideOffset}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
2
2
|
import React, { ComponentProps } from "react";
|
|
3
|
+
import {
|
|
4
|
+
portalScopeProps,
|
|
5
|
+
usePortalScopeId,
|
|
6
|
+
} from "../contexts/PortalScopeContext";
|
|
3
7
|
import { cx } from "../utils/classNames";
|
|
4
8
|
import { IconButton } from "./IconButton";
|
|
5
9
|
|
|
@@ -56,11 +60,14 @@ export function Popover({
|
|
|
56
60
|
onClickClose,
|
|
57
61
|
className,
|
|
58
62
|
}: Props) {
|
|
63
|
+
const portalScopeId = usePortalScopeId();
|
|
64
|
+
|
|
59
65
|
return (
|
|
60
66
|
<PopoverPrimitive.Root open={open} onOpenChange={onOpenChange}>
|
|
61
67
|
<PopoverPrimitive.Trigger asChild>{trigger}</PopoverPrimitive.Trigger>
|
|
62
68
|
<PopoverPrimitive.Portal>
|
|
63
69
|
<PopoverPrimitive.Content
|
|
70
|
+
{...portalScopeProps(portalScopeId)}
|
|
64
71
|
className={cx(
|
|
65
72
|
popoverStyle.base,
|
|
66
73
|
variant === "large" && popoverStyle.large,
|
|
@@ -32,7 +32,6 @@ export interface SegmentedControlProps<T extends string> {
|
|
|
32
32
|
/** @default primary */
|
|
33
33
|
colorScheme?: SegmentedControlColorScheme;
|
|
34
34
|
allowEmpty?: boolean;
|
|
35
|
-
separator?: boolean;
|
|
36
35
|
items: SegmentedControlItemProps<T>[];
|
|
37
36
|
className?: string;
|
|
38
37
|
style?: React.CSSProperties;
|
|
@@ -70,7 +69,7 @@ const SegmentedControlItem = forwardRef(function SegmentedControlItem<
|
|
|
70
69
|
value={(value ?? "").toString()}
|
|
71
70
|
disabled={disabled}
|
|
72
71
|
className={cx(
|
|
73
|
-
"font-sans text-
|
|
72
|
+
"font-sans text-button font-normal relative flex-1 appearance-none text-segmented-control-item rounded inline-flex gap-1.5 items-center justify-center align-middle text-center focus:outline-none transition-colors",
|
|
74
73
|
colorScheme === "secondary"
|
|
75
74
|
? "focus:ring-2 focus:ring-secondary focus:ring-offset-1"
|
|
76
75
|
: "focus:ring-2 focus:ring-primary focus:ring-offset-1",
|
|
@@ -81,7 +80,10 @@ const SegmentedControlItem = forwardRef(function SegmentedControlItem<
|
|
|
81
80
|
: "aria-checked:bg-background aria-checked:text-text",
|
|
82
81
|
"focus:z-interactable",
|
|
83
82
|
"aria-checked:shadow-segment",
|
|
84
|
-
"whitespace-pre",
|
|
83
|
+
"whitespace-pre px-1",
|
|
84
|
+
"border-r border-divider last:border-r-0",
|
|
85
|
+
"aria-checked:border-r-transparent",
|
|
86
|
+
"[&:has(+[aria-checked=true])]:border-r-transparent",
|
|
85
87
|
className
|
|
86
88
|
)}
|
|
87
89
|
{...props}
|
|
@@ -98,15 +100,6 @@ const SegmentedControlItem = forwardRef(function SegmentedControlItem<
|
|
|
98
100
|
);
|
|
99
101
|
});
|
|
100
102
|
|
|
101
|
-
const Separator = ({ transparent }: { transparent: boolean }) => (
|
|
102
|
-
<div
|
|
103
|
-
className={cx(
|
|
104
|
-
"w-[1px] my-1 self-stretch bg-divider",
|
|
105
|
-
transparent && "bg-transparent"
|
|
106
|
-
)}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
|
|
110
103
|
export const SegmentedControl = memoGeneric(function SegmentedControl<
|
|
111
104
|
T extends string,
|
|
112
105
|
>({
|
|
@@ -116,7 +109,6 @@ export const SegmentedControl = memoGeneric(function SegmentedControl<
|
|
|
116
109
|
colorScheme,
|
|
117
110
|
allowEmpty,
|
|
118
111
|
items,
|
|
119
|
-
separator = true,
|
|
120
112
|
className,
|
|
121
113
|
style,
|
|
122
114
|
}: SegmentedControlProps<T>) {
|
|
@@ -131,8 +123,6 @@ export const SegmentedControl = memoGeneric(function SegmentedControl<
|
|
|
131
123
|
[allowEmpty, onValueChange]
|
|
132
124
|
);
|
|
133
125
|
|
|
134
|
-
const selectedIndex = items.findIndex((item) => item?.value === value);
|
|
135
|
-
|
|
136
126
|
return (
|
|
137
127
|
<SegmentedControlContext.Provider value={contextValue}>
|
|
138
128
|
<ToggleGroupPrimitive.Root
|
|
@@ -141,36 +131,17 @@ export const SegmentedControl = memoGeneric(function SegmentedControl<
|
|
|
141
131
|
value={value}
|
|
142
132
|
onValueChange={handleValueChange}
|
|
143
133
|
className={cx(
|
|
144
|
-
`
|
|
134
|
+
`grid appearance-none relative outline-none min-h-input-height rounded bg-input-background py-0.5 px-0.5`,
|
|
145
135
|
className
|
|
146
136
|
)}
|
|
147
|
-
style={
|
|
137
|
+
style={{
|
|
138
|
+
...style,
|
|
139
|
+
gridTemplateColumns: `repeat(${items.length}, 1fr)`,
|
|
140
|
+
}}
|
|
148
141
|
>
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const currentValue = item?.value;
|
|
153
|
-
|
|
154
|
-
// Show separator if:
|
|
155
|
-
// 1. Current item is not selected AND
|
|
156
|
-
// 2. Current item is not immediately before the selected item (except when selected is 0)
|
|
157
|
-
// 3. Current item is not immediately after the selected item
|
|
158
|
-
const showSeparator =
|
|
159
|
-
currentValue !== value &&
|
|
160
|
-
(selectedIndex === 0 && selectedIndex !== index
|
|
161
|
-
? true
|
|
162
|
-
: index !== selectedIndex - 1);
|
|
163
|
-
|
|
164
|
-
return (
|
|
165
|
-
<React.Fragment key={index}>
|
|
166
|
-
<SegmentedControlItem key={index} {...item} />
|
|
167
|
-
{!isLastItem && <Separator transparent={!showSeparator} />}
|
|
168
|
-
</React.Fragment>
|
|
169
|
-
);
|
|
170
|
-
})
|
|
171
|
-
: items.map((item, index) => (
|
|
172
|
-
<SegmentedControlItem key={index} {...item} />
|
|
173
|
-
))}
|
|
142
|
+
{items.map((item, index) => (
|
|
143
|
+
<SegmentedControlItem key={index} {...item} />
|
|
144
|
+
))}
|
|
174
145
|
</ToggleGroupPrimitive.Root>
|
|
175
146
|
</SegmentedControlContext.Provider>
|
|
176
147
|
);
|
|
@@ -15,6 +15,10 @@ import React, {
|
|
|
15
15
|
import { useLabel, useLabelPosition } from "../hooks/useLabel";
|
|
16
16
|
import { cx } from "../utils/classNames";
|
|
17
17
|
|
|
18
|
+
import {
|
|
19
|
+
portalScopeProps,
|
|
20
|
+
usePortalScopeId,
|
|
21
|
+
} from "../contexts/PortalScopeContext";
|
|
18
22
|
import { getInsetEndStyles } from "../utils/inputs";
|
|
19
23
|
import { Button } from "./Button";
|
|
20
24
|
import { renderIcon } from "./Icons";
|
|
@@ -148,6 +152,8 @@ export const SelectMenu = memoGeneric(function SelectMenu<
|
|
|
148
152
|
contentStyle: contentStyleProp,
|
|
149
153
|
...props
|
|
150
154
|
}: Props<T>) {
|
|
155
|
+
const portalScopeId = usePortalScopeId();
|
|
156
|
+
|
|
151
157
|
const selectedItem = items.find(
|
|
152
158
|
(item): item is SelectableMenuItem<T> =>
|
|
153
159
|
isSelectableMenuItem(item) && item.value === value
|
|
@@ -213,6 +219,7 @@ export const SelectMenu = memoGeneric(function SelectMenu<
|
|
|
213
219
|
/>
|
|
214
220
|
<Select.Portal>
|
|
215
221
|
<Select.Content
|
|
222
|
+
{...portalScopeProps(portalScopeId)}
|
|
216
223
|
className={styles.contentStyle}
|
|
217
224
|
position="popper"
|
|
218
225
|
sideOffset={6}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
portalScopeProps,
|
|
3
|
+
usePortalScopeId,
|
|
4
|
+
} from "@noya-app/noya-designsystem";
|
|
2
5
|
import { Rect } from "@noya-app/noya-geometry";
|
|
3
|
-
import {
|
|
6
|
+
import { useSize } from "@noya-app/react-utils";
|
|
4
7
|
import * as PopperPrimitive from "@radix-ui/react-popper";
|
|
5
8
|
import type { MeasurableElement } from "@radix-ui/utils";
|
|
6
|
-
import React, { CSSProperties, useMemo } from "react";
|
|
9
|
+
import React, { CSSProperties, memo, useMemo } from "react";
|
|
7
10
|
|
|
8
11
|
// Create a Measurable from a Rect
|
|
9
12
|
const createVirtualElement = (rect: Rect): MeasurableElement => ({
|
|
@@ -20,51 +23,54 @@ const createVirtualElement = (rect: Rect): MeasurableElement => ({
|
|
|
20
23
|
}),
|
|
21
24
|
});
|
|
22
25
|
|
|
23
|
-
type
|
|
26
|
+
type SelectionToolbarContainerProps = {
|
|
24
27
|
rect: Rect;
|
|
25
|
-
|
|
26
|
-
onSelectMenuItem: (item: T) => void;
|
|
28
|
+
children: React.ReactNode;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
|
-
export const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
export const SelectionToolbarContainer = memo(
|
|
32
|
+
function SelectionToolbarContainer({
|
|
33
|
+
rect,
|
|
34
|
+
children,
|
|
35
|
+
}: SelectionToolbarContainerProps) {
|
|
36
|
+
const portalScopeId = usePortalScopeId();
|
|
37
|
+
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
38
|
+
const size = useSize(containerRef, "width");
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// Create a virtual reference element from the rect
|
|
41
|
+
const virtualRef = useMemo(
|
|
42
|
+
() => ({
|
|
43
|
+
current: createVirtualElement(rect),
|
|
44
|
+
}),
|
|
45
|
+
[rect]
|
|
46
|
+
);
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
>
|
|
61
|
-
<div
|
|
62
|
-
ref={containerRef}
|
|
63
|
-
className="flex gap-1 bg-popover-background rounded shadow-popover p-1"
|
|
48
|
+
return (
|
|
49
|
+
<PopperPrimitive.Root>
|
|
50
|
+
<PopperPrimitive.Anchor virtualRef={virtualRef} />
|
|
51
|
+
<PopperPrimitive.Content
|
|
52
|
+
{...portalScopeProps(portalScopeId)}
|
|
53
|
+
side="top"
|
|
54
|
+
sideOffset={10}
|
|
55
|
+
align="center"
|
|
56
|
+
avoidCollisions
|
|
57
|
+
collisionPadding={10}
|
|
58
|
+
contentEditable={false}
|
|
59
|
+
style={{
|
|
60
|
+
zIndex: 1000,
|
|
61
|
+
opacity: size ? 1 : 0,
|
|
62
|
+
transition: "opacity 0.2s ease-in-out",
|
|
63
|
+
["--n-input-background" as keyof CSSProperties]: "transparent",
|
|
64
|
+
}}
|
|
64
65
|
>
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
<div
|
|
67
|
+
ref={containerRef}
|
|
68
|
+
className="flex gap-1 bg-popover-background rounded shadow-popover p-1"
|
|
69
|
+
>
|
|
70
|
+
{children}
|
|
71
|
+
</div>
|
|
72
|
+
</PopperPrimitive.Content>
|
|
73
|
+
</PopperPrimitive.Root>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
);
|
|
@@ -117,7 +117,7 @@ export const Slider = memo(function Slider({
|
|
|
117
117
|
<div
|
|
118
118
|
style={trackFillStyle}
|
|
119
119
|
className={cx(
|
|
120
|
-
"absolute inset-0 w-full h-full rounded overflow-hidden",
|
|
120
|
+
"absolute inset-0 w-full h-full rounded overflow-hidden bg-primary-pastel",
|
|
121
121
|
colorScheme === "primary" && "bg-primary",
|
|
122
122
|
colorScheme === "secondary" && "bg-secondary"
|
|
123
123
|
)}
|