@noya-app/noya-designsystem 0.1.51 → 0.1.52
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 +11 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +285 -13
- package/dist/index.d.ts +285 -13
- package/dist/index.js +3264 -578
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3235 -550
- 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 +92 -0
- package/src/components/Dialog.tsx +1 -1
- 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 +1 -1
- package/src/components/SegmentedControl.tsx +1 -1
- package/src/components/SelectionToolbar.tsx +70 -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 +11 -1
- package/src/components/Tooltip.tsx +4 -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 +5 -4
- package/src/components/internal/MenuViewport.tsx +2 -0
- package/src/components/pipeline/PipelineResultLayout.tsx +18 -0
- package/src/contexts/DialogContext.tsx +20 -5
- package/src/index.css +101 -39
- package/src/index.tsx +3 -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
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
FileIcon,
|
|
3
|
+
ImageIcon,
|
|
4
|
+
SpeakerLoudIcon,
|
|
5
|
+
VideoIcon,
|
|
6
|
+
} from "@noya-app/noya-icons";
|
|
2
7
|
import React, { memo, useMemo } from "react";
|
|
3
8
|
import { cssVars } from "../theme";
|
|
4
9
|
import { cx } from "../utils/classNames";
|
|
5
10
|
import { CollectionItemSize } from "./Collection";
|
|
6
11
|
import { IconName, Icons } from "./Icons";
|
|
12
|
+
import { fileExtensions, fileNames } from "./catppuccin/fileIcons";
|
|
7
13
|
|
|
8
14
|
type ColorScheme = "primary" | "secondary" | "icon" | "warning";
|
|
9
15
|
|
|
@@ -31,6 +37,8 @@ type MediaThumbnailProps = {
|
|
|
31
37
|
*/
|
|
32
38
|
iconName?: IconName;
|
|
33
39
|
size?: CollectionItemSize;
|
|
40
|
+
|
|
41
|
+
fileName?: string;
|
|
34
42
|
};
|
|
35
43
|
|
|
36
44
|
export const getThumbnailColors = (
|
|
@@ -39,8 +47,8 @@ export const getThumbnailColors = (
|
|
|
39
47
|
) => {
|
|
40
48
|
if (selected) {
|
|
41
49
|
return {
|
|
42
|
-
icon: cssVars.colors.
|
|
43
|
-
background: cssVars.colors.
|
|
50
|
+
icon: cssVars.colors.selectedListItemText,
|
|
51
|
+
background: cssVars.colors.selectedListItemIconBackground,
|
|
44
52
|
};
|
|
45
53
|
}
|
|
46
54
|
|
|
@@ -75,8 +83,9 @@ export const MediaThumbnail = memo(function MediaThumbnail({
|
|
|
75
83
|
className,
|
|
76
84
|
colorScheme = "icon",
|
|
77
85
|
url,
|
|
78
|
-
iconName
|
|
86
|
+
iconName,
|
|
79
87
|
size = "medium",
|
|
88
|
+
fileName,
|
|
80
89
|
}: MediaThumbnailProps) {
|
|
81
90
|
const { icon: iconColor, background: backgroundColor } = getThumbnailColors(
|
|
82
91
|
colorScheme,
|
|
@@ -95,6 +104,7 @@ export const MediaThumbnail = memo(function MediaThumbnail({
|
|
|
95
104
|
switch (contentType) {
|
|
96
105
|
case "image":
|
|
97
106
|
if (!url) return <ImageIcon color={iconColor} style={iconStyles} />;
|
|
107
|
+
|
|
98
108
|
return (
|
|
99
109
|
<img
|
|
100
110
|
src={url}
|
|
@@ -103,18 +113,32 @@ export const MediaThumbnail = memo(function MediaThumbnail({
|
|
|
103
113
|
tabIndex={-1}
|
|
104
114
|
/>
|
|
105
115
|
);
|
|
106
|
-
|
|
107
116
|
case "video":
|
|
108
117
|
return <VideoIcon color={iconColor} style={iconStyles} />;
|
|
109
|
-
|
|
110
118
|
case "audio":
|
|
111
119
|
return <SpeakerLoudIcon color={iconColor} style={iconStyles} />;
|
|
112
|
-
|
|
113
120
|
default:
|
|
114
|
-
|
|
115
|
-
|
|
121
|
+
if (iconName) {
|
|
122
|
+
const Icon = Icons[iconName];
|
|
123
|
+
return <Icon color={iconColor} style={iconStyles} />;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (fileName) {
|
|
127
|
+
const fileIcon = findFileIcon(fileName);
|
|
128
|
+
if (fileIcon) {
|
|
129
|
+
return (
|
|
130
|
+
<img
|
|
131
|
+
src={`https://api.iconify.design/catppuccin/${fileIcon}.svg?height=none&box=1`}
|
|
132
|
+
alt=""
|
|
133
|
+
className="w-4 h-4"
|
|
134
|
+
/>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return <FileIcon color={iconColor} style={iconStyles} />;
|
|
116
140
|
}
|
|
117
|
-
}, [contentType, url, iconColor, iconStyles, iconName]);
|
|
141
|
+
}, [contentType, url, iconColor, iconStyles, iconName, fileName]);
|
|
118
142
|
|
|
119
143
|
return (
|
|
120
144
|
<div
|
|
@@ -137,3 +161,13 @@ const iconSizeMap: Record<CollectionItemSize, number | string> = {
|
|
|
137
161
|
large: "max(15px, 20%)",
|
|
138
162
|
xl: "max(15px, 20%)",
|
|
139
163
|
};
|
|
164
|
+
|
|
165
|
+
function findFileIcon(fileName: string) {
|
|
166
|
+
const fileIcon = fileNames[fileName];
|
|
167
|
+
if (fileIcon) return fileIcon;
|
|
168
|
+
const fileExtensionIndex = fileName.lastIndexOf(".");
|
|
169
|
+
if (fileExtensionIndex === -1) return undefined;
|
|
170
|
+
const fileExtension = fileName.slice(fileExtensionIndex + 1);
|
|
171
|
+
const fileExtensionIcon = fileExtensions[fileExtension];
|
|
172
|
+
return fileExtensionIcon;
|
|
173
|
+
}
|
|
@@ -33,7 +33,7 @@ interface Props
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export const popoverStyle = {
|
|
36
|
-
base: "rounded font-[14px] bg-popover-background shadow-
|
|
36
|
+
base: "rounded font-[14px] bg-popover-background shadow-popover max-h-[600px] overflow-y-auto text-text-muted z-[1000]",
|
|
37
37
|
large: "w-[680px]",
|
|
38
38
|
normal: "w-[240px]",
|
|
39
39
|
};
|
|
@@ -80,7 +80,7 @@ const SegmentedControlItem = forwardRef(function SegmentedControlItem<
|
|
|
80
80
|
? "aria-checked:bg-primary aria-checked:text-white"
|
|
81
81
|
: "aria-checked:bg-background aria-checked:text-text",
|
|
82
82
|
"focus:z-interactable",
|
|
83
|
-
"aria-checked:shadow-
|
|
83
|
+
"aria-checked:shadow-segment",
|
|
84
84
|
"whitespace-pre",
|
|
85
85
|
className
|
|
86
86
|
)}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { MenuItem, ToolbarMenu } from "@noya-app/noya-designsystem";
|
|
2
|
+
import { Rect } from "@noya-app/noya-geometry";
|
|
3
|
+
import { memoGeneric, useSize } from "@noya-app/react-utils";
|
|
4
|
+
import * as PopperPrimitive from "@radix-ui/react-popper";
|
|
5
|
+
import type { MeasurableElement } from "@radix-ui/utils";
|
|
6
|
+
import React, { CSSProperties, useMemo } from "react";
|
|
7
|
+
|
|
8
|
+
// Create a Measurable from a Rect
|
|
9
|
+
const createVirtualElement = (rect: Rect): MeasurableElement => ({
|
|
10
|
+
getBoundingClientRect: () => ({
|
|
11
|
+
width: rect.width,
|
|
12
|
+
height: rect.height,
|
|
13
|
+
x: rect.x,
|
|
14
|
+
y: rect.y,
|
|
15
|
+
top: rect.y,
|
|
16
|
+
right: rect.x + rect.width,
|
|
17
|
+
bottom: rect.y + rect.height,
|
|
18
|
+
left: rect.x,
|
|
19
|
+
toJSON: () => null,
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
type SelectionToolbarProps<T extends string> = {
|
|
24
|
+
rect: Rect;
|
|
25
|
+
menuItems: MenuItem<T>[];
|
|
26
|
+
onSelectMenuItem: (item: T) => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const SelectionToolbar = memoGeneric(function SelectionToolbar<
|
|
30
|
+
T extends string,
|
|
31
|
+
>({ rect, menuItems, onSelectMenuItem }: SelectionToolbarProps<T>) {
|
|
32
|
+
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
33
|
+
const size = useSize(containerRef, "width");
|
|
34
|
+
|
|
35
|
+
// Create a virtual reference element from the rect
|
|
36
|
+
const virtualRef = useMemo(
|
|
37
|
+
() => ({
|
|
38
|
+
current: createVirtualElement(rect),
|
|
39
|
+
}),
|
|
40
|
+
[rect]
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<PopperPrimitive.Root>
|
|
45
|
+
<PopperPrimitive.Anchor virtualRef={virtualRef} />
|
|
46
|
+
<PopperPrimitive.Content
|
|
47
|
+
side="top"
|
|
48
|
+
sideOffset={10}
|
|
49
|
+
align="center"
|
|
50
|
+
avoidCollisions
|
|
51
|
+
collisionPadding={10}
|
|
52
|
+
data-editor-overlay
|
|
53
|
+
contentEditable={false}
|
|
54
|
+
style={{
|
|
55
|
+
zIndex: 1000,
|
|
56
|
+
opacity: size ? 1 : 0,
|
|
57
|
+
transition: "opacity 0.2s ease-in-out",
|
|
58
|
+
["--n-input-background" as keyof CSSProperties]: "transparent",
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<div
|
|
62
|
+
ref={containerRef}
|
|
63
|
+
className="flex gap-1 bg-popover-background rounded shadow-popover p-1"
|
|
64
|
+
>
|
|
65
|
+
<ToolbarMenu items={menuItems} onSelectMenuItem={onSelectMenuItem} />
|
|
66
|
+
</div>
|
|
67
|
+
</PopperPrimitive.Content>
|
|
68
|
+
</PopperPrimitive.Root>
|
|
69
|
+
);
|
|
70
|
+
});
|
|
@@ -38,7 +38,7 @@ export const Switch = function Switch({
|
|
|
38
38
|
onChange(newValue);
|
|
39
39
|
}}
|
|
40
40
|
className={cx(
|
|
41
|
-
"all-unset w-8 h-[19px] bg-active-background rounded-full relative cursor-pointer ring-offset-background [webkit-tap-highlight-color:rgba(0,0,0,0)] focus:ring-2 focus:ring-primary focus:ring-offset-[1px] outline-none data-[state=checked]:bg-primary transition-all",
|
|
41
|
+
"all-unset w-8 h-[19px] bg-active-background rounded-full relative cursor-pointer ring-offset-background [-webkit-tap-highlight-color:rgba(0,0,0,0)] focus:ring-2 focus:ring-primary focus:ring-offset-[1px] outline-none data-[state=checked]:bg-primary transition-all",
|
|
42
42
|
colorScheme === "secondary" && "data-[state=checked]:bg-secondary",
|
|
43
43
|
"focus:z-interactable",
|
|
44
44
|
className
|
package/src/components/Text.tsx
CHANGED
|
@@ -33,8 +33,8 @@ const elements: Record<Variant, keyof ReactHTML> = {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export const textStyles: Record<Variant, string> = {
|
|
36
|
-
title: "font-sans text-title font-bold
|
|
37
|
-
subtitle: "font-sans text-subtitle font-medium
|
|
36
|
+
title: "font-sans text-title font-bold",
|
|
37
|
+
subtitle: "font-sans text-subtitle font-medium",
|
|
38
38
|
heading1: "font-sans text-heading1 font-semibold",
|
|
39
39
|
heading2: "font-sans text-heading2 font-medium",
|
|
40
40
|
heading3: "font-sans text-heading3 font-normal",
|
package/src/components/Toast.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as ToastPrimitive from
|
|
2
|
-
import React, { ReactNode } from
|
|
3
|
-
import { IconButton } from
|
|
4
|
-
import { textStyles } from
|
|
1
|
+
import * as ToastPrimitive from "@radix-ui/react-toast";
|
|
2
|
+
import React, { ReactNode } from "react";
|
|
3
|
+
import { IconButton } from "./IconButton";
|
|
4
|
+
import { textStyles } from "./Text";
|
|
5
5
|
|
|
6
6
|
export const Toast = ({
|
|
7
7
|
title,
|
|
@@ -15,15 +15,21 @@ export const Toast = ({
|
|
|
15
15
|
}) => {
|
|
16
16
|
return (
|
|
17
17
|
<ToastPrimitive.Root
|
|
18
|
-
className="px-2 py-2.5 grid grid-cols-[auto_max-content] gap-x-2.5 items-center rounded text-sm bg-popover-background shadow-
|
|
18
|
+
className="px-2 py-2.5 grid grid-cols-[auto_max-content] gap-x-2.5 items-center rounded text-sm bg-popover-background shadow-popover text-text-muted"
|
|
19
19
|
{...props}
|
|
20
20
|
>
|
|
21
21
|
{title && (
|
|
22
|
-
<ToastPrimitive.Title
|
|
22
|
+
<ToastPrimitive.Title
|
|
23
|
+
className={`mb-[5px] ${textStyles.label} font-bold text-text`}
|
|
24
|
+
>
|
|
23
25
|
{title}
|
|
24
26
|
</ToastPrimitive.Title>
|
|
25
27
|
)}
|
|
26
|
-
<ToastPrimitive.Description
|
|
28
|
+
<ToastPrimitive.Description
|
|
29
|
+
className={`${textStyles.small} text-text-muted`}
|
|
30
|
+
>
|
|
31
|
+
{content}
|
|
32
|
+
</ToastPrimitive.Description>
|
|
27
33
|
{children && (
|
|
28
34
|
<ToastPrimitive.Action asChild altText="">
|
|
29
35
|
{children}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
MenuItem,
|
|
16
16
|
} from "./internal/Menu";
|
|
17
17
|
import { Spacer } from "./Spacer";
|
|
18
|
+
import { Tooltip } from "./Tooltip";
|
|
18
19
|
|
|
19
20
|
export interface ToolbarProps<T extends string = string> {
|
|
20
21
|
children?: React.ReactNode;
|
|
@@ -81,6 +82,7 @@ export function Toolbar<T extends string = string>({
|
|
|
81
82
|
|
|
82
83
|
const activeButtonStyle = {
|
|
83
84
|
backgroundColor: cssVars.colors.primaryPastel,
|
|
85
|
+
color: cssVars.colors.primary,
|
|
84
86
|
};
|
|
85
87
|
|
|
86
88
|
export const ToolbarMenu = memoGeneric(function ToolbarMenu<T extends string>({
|
|
@@ -100,7 +102,7 @@ export const ToolbarMenu = memoGeneric(function ToolbarMenu<T extends string>({
|
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
if (isSelectableMenuItem(item)) {
|
|
103
|
-
|
|
105
|
+
const content = (
|
|
104
106
|
<Button
|
|
105
107
|
key={i}
|
|
106
108
|
disabled={item.disabled}
|
|
@@ -116,6 +118,14 @@ export const ToolbarMenu = memoGeneric(function ToolbarMenu<T extends string>({
|
|
|
116
118
|
{item.icon && renderIcon(item.icon)}
|
|
117
119
|
</Button>
|
|
118
120
|
);
|
|
121
|
+
|
|
122
|
+
return item.tooltip ? (
|
|
123
|
+
<Tooltip sideOffset={10} content={item.tooltip} key={i}>
|
|
124
|
+
{content}
|
|
125
|
+
</Tooltip>
|
|
126
|
+
) : (
|
|
127
|
+
content
|
|
128
|
+
);
|
|
119
129
|
}
|
|
120
130
|
|
|
121
131
|
return (
|
|
@@ -9,11 +9,13 @@ import { textStyles } from "./Text";
|
|
|
9
9
|
interface Props {
|
|
10
10
|
children: React.ReactNode;
|
|
11
11
|
content: React.ReactNode;
|
|
12
|
+
sideOffset?: number;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export const Tooltip = React.memo(function Tooltip({
|
|
15
16
|
children,
|
|
16
17
|
content,
|
|
18
|
+
sideOffset = 2,
|
|
17
19
|
}: Props) {
|
|
18
20
|
return (
|
|
19
21
|
<TooltipPrimitive.Provider>
|
|
@@ -23,9 +25,9 @@ export const Tooltip = React.memo(function Tooltip({
|
|
|
23
25
|
<TooltipPrimitive.Content
|
|
24
26
|
side="bottom"
|
|
25
27
|
align="center"
|
|
26
|
-
sideOffset={
|
|
28
|
+
sideOffset={sideOffset}
|
|
27
29
|
collisionPadding={8}
|
|
28
|
-
className={`${textStyles.small} text-text rounded-[3px] py-small px-medium bg-popover-background shadow-
|
|
30
|
+
className={`${textStyles.small} text-text rounded-[3px] py-small px-medium bg-popover-background shadow-popover border border-solid border-divider-strong z-menu`}
|
|
29
31
|
>
|
|
30
32
|
{content}
|
|
31
33
|
{/* <Arrow /> */}
|