@noya-app/noya-designsystem 0.1.51 → 0.1.53
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 -13
- package/CHANGELOG.md +17 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +307 -12
- package/dist/index.d.ts +307 -12
- package/dist/index.js +3408 -647
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3660 -908
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -9
- package/postcss.config.js +7 -0
- package/src/components/ActionMenu.tsx +8 -3
- package/src/components/Banner.tsx +2 -2
- package/src/components/BaseToolbar.tsx +6 -2
- package/src/components/Breadcrumbs.tsx +32 -2
- package/src/components/Button.tsx +30 -19
- package/src/components/Chip.tsx +3 -0
- package/src/components/ColorSwatch.tsx +42 -0
- package/src/components/ColorSwatchControl.tsx +90 -0
- package/src/components/ContextMenu.tsx +10 -2
- package/src/components/Dialog.tsx +1 -1
- package/src/components/DraggableMenuButton.tsx +17 -30
- package/src/components/DropdownMenu.tsx +7 -0
- package/src/components/FillInputField.tsx +1 -1
- package/src/components/Grid.tsx +11 -4
- package/src/components/GridView.tsx +1 -1
- package/src/components/LabeledField.tsx +4 -1
- package/src/components/List.tsx +12 -7
- package/src/components/ListView.tsx +7 -4
- package/src/components/MediaThumbnail.tsx +44 -10
- package/src/components/Popover.tsx +8 -1
- package/src/components/SegmentedControl.tsx +1 -1
- package/src/components/SelectMenu.tsx +7 -0
- package/src/components/SelectionToolbar.tsx +76 -0
- package/src/components/Switch.tsx +1 -1
- package/src/components/Text.tsx +2 -2
- package/src/components/Toast.tsx +13 -7
- package/src/components/Toolbar.tsx +78 -37
- package/src/components/Tooltip.tsx +11 -2
- package/src/components/catppuccin/fileIcons.ts +2430 -0
- package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +3 -1
- package/src/components/internal/Menu.tsx +6 -5
- package/src/components/internal/MenuViewport.tsx +11 -1
- package/src/components/pipeline/PipelineResultLayout.tsx +18 -0
- package/src/contexts/DialogContext.tsx +20 -5
- package/src/contexts/PortalScopeContext.tsx +48 -0
- package/src/index.css +101 -39
- package/src/index.tsx +4 -0
- package/src/theme/index.ts +6 -1
- package/src/theme/themeUtils.ts +10 -3
- package/src/utils/classNames.ts +3 -2
- package/src/utils/moveTreeItem.ts +4 -4
- package/tsup.config.ts +1 -1
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.53",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"./index.css": "./dist/index.css"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build:css": "tailwindcss -i ./src/index.css -o ./dist/index.css",
|
|
17
|
+
"build:css": "tailwindcss -i ./src/index.css -o ./dist/index.css --postcss",
|
|
18
18
|
"build": "tsup",
|
|
19
19
|
"dev": "npm run build -- --watch",
|
|
20
20
|
"lint": "eslint . --max-warnings 0"
|
|
@@ -22,12 +22,12 @@
|
|
|
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.20",
|
|
26
26
|
"@noya-app/noya-utils": "0.1.5",
|
|
27
|
-
"@noya-app/noya-geometry": "0.1.
|
|
28
|
-
"@noya-app/noya-icons": "0.1.
|
|
27
|
+
"@noya-app/noya-geometry": "0.1.11",
|
|
28
|
+
"@noya-app/noya-icons": "0.1.8",
|
|
29
29
|
"@noya-app/noya-keymap": "0.1.3",
|
|
30
|
-
"@noya-app/noya-tailwind-config": "0.1.
|
|
30
|
+
"@noya-app/noya-tailwind-config": "0.1.3",
|
|
31
31
|
"@radix-ui/primitive": "^1.0.0",
|
|
32
32
|
"@radix-ui/react-avatar": "^1.0.1",
|
|
33
33
|
"@radix-ui/react-compose-refs": "^1.0.0",
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
"@radix-ui/react-tooltip": "^1.0.2",
|
|
45
45
|
"@radix-ui/react-utils": "^0.0.5",
|
|
46
46
|
"@radix-ui/react-select": "^2.1.1",
|
|
47
|
+
"@radix-ui/react-popper": "1.2.3",
|
|
48
|
+
"@radix-ui/utils": "0.0.3",
|
|
47
49
|
"immer": "9.0.5",
|
|
48
50
|
"kiwi.js": "^1.1.3",
|
|
49
51
|
"react-resizable-panels": "2.0.22",
|
|
@@ -57,9 +59,10 @@
|
|
|
57
59
|
"@types/react-dom": "*",
|
|
58
60
|
"@types/react-virtualized": "^9.21.30",
|
|
59
61
|
"@types/react-window": "^1.8.5",
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
62
|
+
"tailwindcss": "^3.4.17",
|
|
63
|
+
"postcss": "^8.5.3",
|
|
64
|
+
"autoprefixer": "^10.4.21",
|
|
65
|
+
"postcss-nested": "^7.0.2"
|
|
63
66
|
},
|
|
64
67
|
"peerDependencies": {
|
|
65
68
|
"react": "*",
|
|
@@ -8,11 +8,13 @@ import { MenuItem } from "./internal/Menu";
|
|
|
8
8
|
type ActionMenuProps<TMenu extends string> = {
|
|
9
9
|
menuItems: MenuItem<TMenu>[];
|
|
10
10
|
onSelect: (action: TMenu) => void;
|
|
11
|
-
selected
|
|
12
|
-
|
|
11
|
+
selected?: boolean;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
onOpenChange?: (open: boolean) => void;
|
|
13
14
|
className?: string;
|
|
14
15
|
style?: React.CSSProperties;
|
|
15
16
|
variant?: "normal" | "bare";
|
|
17
|
+
color?: string;
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
export const ActionMenu = memoGeneric(function ActionMenu<
|
|
@@ -22,9 +24,11 @@ export const ActionMenu = memoGeneric(function ActionMenu<
|
|
|
22
24
|
onSelect,
|
|
23
25
|
selected,
|
|
24
26
|
onOpenChange,
|
|
27
|
+
disabled,
|
|
25
28
|
className,
|
|
26
29
|
style,
|
|
27
30
|
variant = "normal",
|
|
31
|
+
color,
|
|
28
32
|
}: ActionMenuProps<TMenu>) {
|
|
29
33
|
const internalStyle = useMemo(() => {
|
|
30
34
|
return {
|
|
@@ -46,7 +50,8 @@ export const ActionMenu = memoGeneric(function ActionMenu<
|
|
|
46
50
|
style={internalStyle}
|
|
47
51
|
className={className}
|
|
48
52
|
iconName="DotsVerticalIcon"
|
|
49
|
-
color={selected ? cssVars.colors.primary :
|
|
53
|
+
color={color ?? (selected ? cssVars.colors.primary : "currentColor")}
|
|
54
|
+
disabled={disabled}
|
|
50
55
|
/>
|
|
51
56
|
</DropdownMenu>
|
|
52
57
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { CSSProperties } from "react";
|
|
1
|
+
import React, { CSSProperties, ReactNode } from "react";
|
|
2
2
|
import { cssVars } from "../theme";
|
|
3
3
|
import { cx } from "../utils/classNames";
|
|
4
4
|
import { Small } from "./Text";
|
|
@@ -9,7 +9,7 @@ const bannerStyles = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export type BannerProps = {
|
|
12
|
-
label?:
|
|
12
|
+
label?: ReactNode;
|
|
13
13
|
className?: string;
|
|
14
14
|
style?: CSSProperties;
|
|
15
15
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { cssVars } from "../theme";
|
|
2
|
+
import { cssVarNames, cssVars } from "../theme";
|
|
3
3
|
import { Divider, DividerVertical } from "./Divider";
|
|
4
4
|
import { Spacer } from "./Spacer";
|
|
5
5
|
|
|
@@ -11,6 +11,10 @@ export interface BaseToolbarProps {
|
|
|
11
11
|
showDivider?: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const toolbarStyle = {
|
|
15
|
+
[cssVarNames.colors.inputBackground]: "transparent",
|
|
16
|
+
};
|
|
17
|
+
|
|
14
18
|
export function BaseToolbar({
|
|
15
19
|
children,
|
|
16
20
|
left,
|
|
@@ -19,7 +23,7 @@ export function BaseToolbar({
|
|
|
19
23
|
showDivider = true,
|
|
20
24
|
}: BaseToolbarProps) {
|
|
21
25
|
return (
|
|
22
|
-
<div className="flex flex-col">
|
|
26
|
+
<div className="flex flex-col" style={toolbarStyle}>
|
|
23
27
|
<div
|
|
24
28
|
className="flex items-center pr-2.5 bg-sidebar-background flex-none relative @container/toolbar"
|
|
25
29
|
style={{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { forwardRef } from "react";
|
|
2
2
|
|
|
3
3
|
import React from "react";
|
|
4
|
+
import { cssVars } from "../theme";
|
|
4
5
|
import { cx } from "../utils/classNames";
|
|
5
6
|
import { Text, TextProps } from "./Text";
|
|
6
7
|
|
|
@@ -10,7 +11,7 @@ type BreadcrumbTextProps = Omit<
|
|
|
10
11
|
>;
|
|
11
12
|
|
|
12
13
|
export const BreadcrumbText = forwardRef(function BreadcrumbText(
|
|
13
|
-
{ children, className, ...props }: BreadcrumbTextProps,
|
|
14
|
+
{ children, className, onClick, ...props }: BreadcrumbTextProps,
|
|
14
15
|
ref: React.ForwardedRef<HTMLSpanElement>
|
|
15
16
|
) {
|
|
16
17
|
return (
|
|
@@ -18,12 +19,41 @@ export const BreadcrumbText = forwardRef(function BreadcrumbText(
|
|
|
18
19
|
{...props}
|
|
19
20
|
variant="small"
|
|
20
21
|
className={cx(
|
|
21
|
-
"
|
|
22
|
+
"whitespace-pre leading-[15px] select-none",
|
|
23
|
+
onClick &&
|
|
24
|
+
"hover:text-breadcrumb-text-hover hover:cursor-pointer hover:whitespace-pre hover:select-none",
|
|
22
25
|
className
|
|
23
26
|
)}
|
|
24
27
|
ref={ref}
|
|
28
|
+
onClick={onClick}
|
|
25
29
|
>
|
|
26
30
|
{children}
|
|
27
31
|
</Text>
|
|
28
32
|
);
|
|
29
33
|
});
|
|
34
|
+
|
|
35
|
+
const slashStyle = {
|
|
36
|
+
margin: "0 3px",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const BreadcrumbSlash = () => {
|
|
40
|
+
return (
|
|
41
|
+
<svg
|
|
42
|
+
width="7"
|
|
43
|
+
height="17"
|
|
44
|
+
viewBox="0 0 7 17"
|
|
45
|
+
fill="none"
|
|
46
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
47
|
+
opacity={0.5}
|
|
48
|
+
style={slashStyle}
|
|
49
|
+
>
|
|
50
|
+
<path
|
|
51
|
+
d="M1 16L6 1"
|
|
52
|
+
stroke={cssVars.colors.breadcrumbIcon}
|
|
53
|
+
strokeWidth="1.2"
|
|
54
|
+
strokeLinecap="round"
|
|
55
|
+
strokeLinejoin="round"
|
|
56
|
+
/>
|
|
57
|
+
</svg>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
@@ -4,8 +4,9 @@ import React, {
|
|
|
4
4
|
forwardRef,
|
|
5
5
|
ReactNode,
|
|
6
6
|
useCallback,
|
|
7
|
+
useMemo,
|
|
7
8
|
} from "react";
|
|
8
|
-
import { cx } from "../utils/classNames";
|
|
9
|
+
import { cx, mergeConflictingClassNames } from "../utils/classNames";
|
|
9
10
|
import { Tooltip } from "./Tooltip";
|
|
10
11
|
|
|
11
12
|
type ButtonVariant =
|
|
@@ -61,6 +62,7 @@ export interface ButtonRootProps {
|
|
|
61
62
|
href?: string;
|
|
62
63
|
target?: string;
|
|
63
64
|
rel?: string;
|
|
65
|
+
download?: string;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
export const Button = forwardRef(function Button(
|
|
@@ -82,28 +84,37 @@ export const Button = forwardRef(function Button(
|
|
|
82
84
|
}: ButtonRootProps,
|
|
83
85
|
forwardedRef: ForwardedRef<HTMLButtonElement>
|
|
84
86
|
) {
|
|
87
|
+
const baseClassName = cx(
|
|
88
|
+
"no-underline leading-[1] relative border-0 outline-none select-none text-left rounded flex items-center justify-center [&>*]:pointer-events-none [-webkit-app-region:no-drag] focus:ring-2 focus:ring-primary focus:shadow-[0_0_0_1px_var(--n-popover-background)_inset] transition-all",
|
|
89
|
+
disabled ? "opacity-25" : "",
|
|
90
|
+
!className?.includes("flex") ? "flex-none" : "",
|
|
91
|
+
active
|
|
92
|
+
? "bg-primary-pastel text-primary hover:bg-primary-pastel-light min-w-[31px]"
|
|
93
|
+
: variantStyles[variant],
|
|
94
|
+
sizeStyles[
|
|
95
|
+
variant === "thin"
|
|
96
|
+
? "thin"
|
|
97
|
+
: variant === "floating" && size !== "small"
|
|
98
|
+
? "floating"
|
|
99
|
+
: variant === "none"
|
|
100
|
+
? "none"
|
|
101
|
+
: size
|
|
102
|
+
]
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const buttonClassName = useMemo(() => {
|
|
106
|
+
return className
|
|
107
|
+
? mergeConflictingClassNames([baseClassName, className], {
|
|
108
|
+
categories: ["position"],
|
|
109
|
+
})
|
|
110
|
+
: baseClassName;
|
|
111
|
+
}, [className, baseClassName]);
|
|
112
|
+
|
|
85
113
|
const buttonElement = (
|
|
86
114
|
<Component
|
|
87
115
|
ref={forwardedRef}
|
|
88
116
|
id={id}
|
|
89
|
-
className={
|
|
90
|
-
"no-underline leading-[1] relative border-0 outline-none select-none text-left rounded flex items-center justify-center [&>*]:pointer-events-none [-webkit-app-region:no-drag] focus:ring-2 focus:ring-primary focus:shadow-[0_0_0_1px_var(--n-popover-background)_inset] transition-all",
|
|
91
|
-
disabled ? "opacity-25" : "",
|
|
92
|
-
!className?.includes("flex") ? "flex-none" : "",
|
|
93
|
-
active
|
|
94
|
-
? "bg-primary text-white hover:bg-primary-light active:bg-primary"
|
|
95
|
-
: variantStyles[variant],
|
|
96
|
-
sizeStyles[
|
|
97
|
-
variant === "thin"
|
|
98
|
-
? "thin"
|
|
99
|
-
: variant === "floating" && size !== "small"
|
|
100
|
-
? "floating"
|
|
101
|
-
: variant === "none"
|
|
102
|
-
? "none"
|
|
103
|
-
: size
|
|
104
|
-
],
|
|
105
|
-
className
|
|
106
|
-
)}
|
|
117
|
+
className={buttonClassName}
|
|
107
118
|
style={style}
|
|
108
119
|
tabIndex={tabIndex}
|
|
109
120
|
disabled={disabled}
|
package/src/components/Chip.tsx
CHANGED
|
@@ -83,6 +83,7 @@ export interface ChipProps {
|
|
|
83
83
|
style?: React.CSSProperties;
|
|
84
84
|
tabIndex?: number;
|
|
85
85
|
role?: string;
|
|
86
|
+
disabled?: boolean;
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
export const Chip = memo(
|
|
@@ -103,6 +104,7 @@ export const Chip = memo(
|
|
|
103
104
|
onAdd,
|
|
104
105
|
onHoverDeleteChange,
|
|
105
106
|
className,
|
|
107
|
+
disabled,
|
|
106
108
|
...rest
|
|
107
109
|
}: ChipProps,
|
|
108
110
|
forwardedRef: React.ForwardedRef<HTMLSpanElement>
|
|
@@ -128,6 +130,7 @@ export const Chip = memo(
|
|
|
128
130
|
monospace && "font-mono",
|
|
129
131
|
variantClasses,
|
|
130
132
|
isInteractive && "cursor-pointer hover:opacity-85",
|
|
133
|
+
disabled && "opacity-50",
|
|
131
134
|
className
|
|
132
135
|
);
|
|
133
136
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
export type ColorSwatchSize = "xsmall" | "small" | "medium" | "large";
|
|
4
|
+
|
|
5
|
+
export const colorSwatchSizeMap = {
|
|
6
|
+
xsmall: 21,
|
|
7
|
+
small: 27,
|
|
8
|
+
medium: 36,
|
|
9
|
+
large: 48,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type ColorSwatchProps = {
|
|
13
|
+
color: string;
|
|
14
|
+
size?: ColorSwatchSize;
|
|
15
|
+
checked?: boolean;
|
|
16
|
+
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
17
|
+
|
|
18
|
+
export const ColorSwatch = forwardRef(function ColorSwatch(
|
|
19
|
+
{ color, size = "small", checked, style, ...props }: ColorSwatchProps,
|
|
20
|
+
ref: React.ForwardedRef<HTMLButtonElement>
|
|
21
|
+
) {
|
|
22
|
+
const sizePx = colorSwatchSizeMap[size];
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<button
|
|
26
|
+
{...props}
|
|
27
|
+
ref={ref}
|
|
28
|
+
style={{
|
|
29
|
+
background: color,
|
|
30
|
+
width: sizePx,
|
|
31
|
+
height: sizePx,
|
|
32
|
+
borderRadius: "4px",
|
|
33
|
+
outline: checked
|
|
34
|
+
? "2px solid rgba(0,0,0,0.2)"
|
|
35
|
+
: "1px solid rgba(0,0,0,0.1)",
|
|
36
|
+
outlineOffset: -1,
|
|
37
|
+
boxShadow: checked ? `inset 0 0 0 2px rgba(0,0,0,0.2)` : undefined,
|
|
38
|
+
...style,
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
2
|
+
import React, { useMemo } from "react";
|
|
3
|
+
import { cx } from "../utils/classNames";
|
|
4
|
+
import {
|
|
5
|
+
ColorSwatch,
|
|
6
|
+
ColorSwatchSize,
|
|
7
|
+
colorSwatchSizeMap,
|
|
8
|
+
} from "./ColorSwatch";
|
|
9
|
+
|
|
10
|
+
export type TokenValue = string | { ref: string };
|
|
11
|
+
|
|
12
|
+
type ColorSwatchControlProps = {
|
|
13
|
+
options: TokenValue[];
|
|
14
|
+
value?: TokenValue;
|
|
15
|
+
/** @default "small" */
|
|
16
|
+
size?: ColorSwatchSize;
|
|
17
|
+
readOnly?: boolean;
|
|
18
|
+
onValueChange?: (value: TokenValue) => void;
|
|
19
|
+
onFocus?: React.FocusEventHandler<HTMLButtonElement>;
|
|
20
|
+
onBlur?: React.FocusEventHandler<HTMLButtonElement>;
|
|
21
|
+
className?: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
style?: React.CSSProperties;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function ColorSwatchControl(props: ColorSwatchControlProps) {
|
|
28
|
+
const {
|
|
29
|
+
options,
|
|
30
|
+
size = "small",
|
|
31
|
+
readOnly,
|
|
32
|
+
value,
|
|
33
|
+
onValueChange,
|
|
34
|
+
onFocus,
|
|
35
|
+
onBlur,
|
|
36
|
+
disabled,
|
|
37
|
+
className,
|
|
38
|
+
id,
|
|
39
|
+
style,
|
|
40
|
+
} = props;
|
|
41
|
+
const styles = useMemo(() => {
|
|
42
|
+
return {
|
|
43
|
+
display: "grid",
|
|
44
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${colorSwatchSizeMap[size]}px, 1fr))`,
|
|
45
|
+
gap: "6px",
|
|
46
|
+
...style,
|
|
47
|
+
};
|
|
48
|
+
}, [size, style]);
|
|
49
|
+
|
|
50
|
+
const content = (
|
|
51
|
+
<div className={className} id={id} style={styles}>
|
|
52
|
+
{options.map((option) => {
|
|
53
|
+
const item = (
|
|
54
|
+
<ColorSwatch
|
|
55
|
+
key={option as string}
|
|
56
|
+
color={option as string}
|
|
57
|
+
size={size}
|
|
58
|
+
onFocus={onFocus}
|
|
59
|
+
onBlur={onBlur}
|
|
60
|
+
disabled={disabled}
|
|
61
|
+
// TODO: decide on "checked" visual treatment
|
|
62
|
+
className={cx(readOnly ? "cursor-default" : "cursor-pointer")}
|
|
63
|
+
checked={value === option}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
return (
|
|
67
|
+
<ToggleGroupPrimitive.Item
|
|
68
|
+
asChild
|
|
69
|
+
value={option as string}
|
|
70
|
+
key={option as string}
|
|
71
|
+
disabled={readOnly}
|
|
72
|
+
>
|
|
73
|
+
{item}
|
|
74
|
+
</ToggleGroupPrimitive.Item>
|
|
75
|
+
);
|
|
76
|
+
})}
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
return (
|
|
80
|
+
<ToggleGroupPrimitive.Root
|
|
81
|
+
type="single"
|
|
82
|
+
value={value as string}
|
|
83
|
+
onValueChange={onValueChange}
|
|
84
|
+
className="w-full"
|
|
85
|
+
disabled={readOnly}
|
|
86
|
+
>
|
|
87
|
+
{content}
|
|
88
|
+
</ToggleGroupPrimitive.Root>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -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}
|
|
@@ -35,7 +35,7 @@ const StyledContent = forwardRef<
|
|
|
35
35
|
w-[90vw] max-w-[450px] max-h-[85vh] p-dialog-padding rounded-[2px]
|
|
36
36
|
font-sans text-heading5 font-normal leading-[19px] text-text-muted
|
|
37
37
|
bg-popover-background pointer-events-all z-[1000] focus:outline-none
|
|
38
|
-
shadow-
|
|
38
|
+
shadow-dialog-shadow
|
|
39
39
|
flex flex-col
|
|
40
40
|
`,
|
|
41
41
|
className
|
|
@@ -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}
|
|
@@ -11,7 +11,7 @@ const FillButton = forwardRef<
|
|
|
11
11
|
<button
|
|
12
12
|
ref={ref}
|
|
13
13
|
className={cx(
|
|
14
|
-
`outline-none p-0 w-[50px] h-input-height rounded overflow-hidden border-none shadow-[0_0_0_1px_var(--n-divider)_inset] bg-transparent relative focus:shadow-
|
|
14
|
+
`outline-none p-0 w-[50px] h-input-height rounded overflow-hidden border-none shadow-[0_0_0_1px_var(--n-divider)_inset] bg-transparent relative focus:shadow-active-input `,
|
|
15
15
|
className
|
|
16
16
|
)}
|
|
17
17
|
{...props}
|
package/src/components/Grid.tsx
CHANGED
|
@@ -154,7 +154,10 @@ export const Grid = memoGeneric(
|
|
|
154
154
|
scrollable={items.length > 0 && scrollable}
|
|
155
155
|
contentClassName={cx(items.length === 0 && "flex flex-1")}
|
|
156
156
|
gap={gap}
|
|
157
|
-
className={cx(
|
|
157
|
+
className={cx(
|
|
158
|
+
isDropTargetActive && "bg-selected-list-item-background",
|
|
159
|
+
className
|
|
160
|
+
)}
|
|
158
161
|
{...dropTargetProps}
|
|
159
162
|
ref={fileDropTargetRef}
|
|
160
163
|
>
|
|
@@ -232,7 +235,7 @@ export const Grid = memoGeneric(
|
|
|
232
235
|
<span
|
|
233
236
|
{...props}
|
|
234
237
|
className={cx(
|
|
235
|
-
isSelected && "text-
|
|
238
|
+
isSelected && "text-selected-list-item-text",
|
|
236
239
|
"truncate select-none"
|
|
237
240
|
)}
|
|
238
241
|
/>
|
|
@@ -240,7 +243,11 @@ export const Grid = memoGeneric(
|
|
|
240
243
|
</EditableText>
|
|
241
244
|
}
|
|
242
245
|
subtitle={
|
|
243
|
-
<span
|
|
246
|
+
<span
|
|
247
|
+
className={cx(
|
|
248
|
+
isSelected && "text-selected-list-item-text"
|
|
249
|
+
)}
|
|
250
|
+
>
|
|
244
251
|
{renderDetail?.(item, isSelected)}
|
|
245
252
|
</span>
|
|
246
253
|
}
|
|
@@ -274,7 +281,7 @@ export const Grid = memoGeneric(
|
|
|
274
281
|
<div
|
|
275
282
|
className={cx(
|
|
276
283
|
"rounded overflow-hidden flex-none flex w-full",
|
|
277
|
-
isSelected && "text-
|
|
284
|
+
isSelected && "text-selected-list-item-text"
|
|
278
285
|
)}
|
|
279
286
|
tabIndex={-1}
|
|
280
287
|
>
|
|
@@ -166,7 +166,7 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
|
|
|
166
166
|
"flex flex-col relative rounded p-2 -m-2 text-text",
|
|
167
167
|
"cursor-pointer",
|
|
168
168
|
"active:opacity-70",
|
|
169
|
-
selected && "bg-
|
|
169
|
+
selected && "bg-selected-list-item-background",
|
|
170
170
|
hovered && "bg-list-view-hover-background",
|
|
171
171
|
disabled && "opacity-50",
|
|
172
172
|
showInsideDropIndicator && "ring-2 ring-primary ring-inset",
|