@noya-app/noya-designsystem 0.1.63 → 0.1.65
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 +13 -10
- package/CHANGELOG.md +25 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +648 -333
- package/dist/index.d.ts +648 -333
- package/dist/index.js +13813 -9157
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13949 -9269
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -22
- package/src/__tests__/validateDropIndicator.test.ts +26 -41
- package/src/__tests__/workspaceLayout.test.ts +281 -0
- package/src/components/ActionMenu.tsx +2 -0
- package/src/components/ActivityIndicator.tsx +13 -6
- package/src/components/ActivityLog.tsx +197 -0
- package/src/components/AnimatePresence.tsx +43 -26
- package/src/components/Avatar.tsx +45 -26
- package/src/components/Banner.tsx +57 -11
- package/src/components/BaseToolbar.tsx +67 -34
- package/src/components/Breadcrumbs.tsx +4 -2
- package/src/components/Button.tsx +28 -23
- package/src/components/Checkbox.tsx +6 -35
- package/src/components/Chip.tsx +47 -33
- package/src/components/Collection.tsx +20 -12
- package/src/components/ColorSwatch.tsx +42 -22
- package/src/components/ColorSwatchControl.tsx +7 -5
- package/src/components/Combobox.tsx +8 -6
- package/src/components/ComboboxMenu.tsx +6 -5
- package/src/components/CommandPalette.tsx +3 -1
- package/src/components/ContextMenu.tsx +3 -1
- package/src/components/Dialog.tsx +9 -13
- package/src/components/DimensionInput.tsx +2 -0
- package/src/components/Divider.tsx +18 -14
- package/src/components/DraggableMenuButton.tsx +11 -5
- package/src/components/Drawer.tsx +14 -6
- package/src/components/DropdownMenu.tsx +4 -2
- package/src/components/EditableText.tsx +4 -2
- package/src/components/Fade.tsx +13 -13
- package/src/components/FileUploadIndicator.tsx +108 -0
- package/src/components/FloatingWindow.tsx +4 -2
- package/src/components/Grid.tsx +58 -42
- package/src/components/GridView.tsx +65 -36
- package/src/components/IVirtualizedList.tsx +5 -0
- package/src/components/IconButton.tsx +2 -0
- package/src/components/Icons.tsx +24 -4
- package/src/components/InputField.tsx +21 -19
- package/src/components/InspectorContainer.tsx +2 -2
- package/src/components/InspectorPrimitives.tsx +15 -9
- package/src/components/Label.tsx +4 -3
- package/src/components/LabeledElementView.tsx +9 -5
- package/src/components/LabeledField.tsx +8 -6
- package/src/components/List.tsx +112 -46
- package/src/components/ListMenu.tsx +91 -0
- package/src/components/ListNavigator.tsx +106 -0
- package/src/components/ListView.tsx +22 -1147
- package/src/components/MediaThumbnail.tsx +84 -14
- package/src/components/Message.tsx +11 -12
- package/src/components/Navigator.tsx +461 -0
- package/src/components/NoyaLogo.tsx +1 -1
- package/src/components/Popover.tsx +12 -6
- package/src/components/Progress.tsx +31 -8
- package/src/components/ResizableContainer.tsx +187 -0
- package/src/components/RingProgress.tsx +128 -0
- package/src/components/ScrollArea.tsx +7 -5
- package/src/components/ScrollableSidebar.tsx +10 -0
- package/src/components/SearchCompletionMenu.tsx +5 -3
- package/src/components/Section.tsx +109 -57
- package/src/components/SegmentedControl.tsx +51 -25
- package/src/components/SelectMenu.tsx +16 -21
- package/src/components/SelectionToolbar.tsx +7 -4
- package/src/components/Slider.tsx +12 -10
- package/src/components/Spacer.tsx +2 -2
- package/src/components/StackNavigator.tsx +378 -0
- package/src/components/Stepper.tsx +88 -0
- package/src/components/Switch.tsx +7 -5
- package/src/components/Tabs.tsx +6 -4
- package/src/components/Text.tsx +29 -18
- package/src/components/TextArea.tsx +5 -3
- package/src/components/Toast.tsx +5 -5
- package/src/components/Toolbar.tsx +57 -10
- package/src/components/ToolbarDrawer.tsx +29 -0
- package/src/components/Tooltip.tsx +2 -2
- package/src/components/TreeView.tsx +13 -4
- package/src/components/UserPointer.tsx +6 -4
- package/src/components/ai-assistant/AIAssistantLayout.tsx +10 -8
- package/src/components/blocks/ImageBlockComponent.tsx +162 -0
- package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +6 -4
- package/src/components/file-explorer/FileExplorerLayout.tsx +22 -8
- package/src/components/internal/Checkmark.tsx +24 -0
- package/src/components/internal/Menu.tsx +24 -19
- package/src/components/internal/MenuViewport.tsx +15 -6
- package/src/components/internal/SelectItem.tsx +7 -26
- package/src/components/internal/TextInput.tsx +7 -1
- package/src/components/listView/ListViewContexts.tsx +68 -0
- package/src/components/listView/ListViewEditableRowTitle.tsx +55 -0
- package/src/components/listView/ListViewRoot.tsx +521 -0
- package/src/components/listView/ListViewRow.tsx +475 -0
- package/src/components/listView/ListViewRowTitle.tsx +21 -0
- package/src/components/listView/types.ts +11 -0
- package/src/components/pipeline/PipelineResultLayout.tsx +6 -6
- package/src/components/sorting/DragRegistration.tsx +10 -5
- package/src/components/sorting/SharedDragProvider.tsx +134 -27
- package/src/components/sorting/Sortable.tsx +90 -27
- package/src/components/sorting/createSharedDrag.tsx +7 -6
- package/src/components/sorting/sorting.ts +6 -9
- package/src/components/workspace/DrawerWorkspaceLayout.tsx +110 -29
- package/src/components/workspace/PanelWorkspaceLayout.tsx +148 -99
- package/src/components/workspace/VerticalTabMenu.tsx +46 -0
- package/src/components/workspace/WorkspaceLayout.tsx +76 -63
- package/src/components/workspace/constants.ts +4 -0
- package/src/components/workspace/panelStorage.ts +216 -0
- package/src/components/workspace/types.ts +11 -4
- package/src/contexts/DesignSystemConfiguration.tsx +12 -5
- package/src/contexts/DialogContext.tsx +19 -5
- package/src/contexts/FloatingWindowContext.tsx +2 -0
- package/src/contexts/GlobalInputBlurContext.tsx +2 -0
- package/src/contexts/ImageDataContext.tsx +2 -0
- package/src/contexts/LinkComponentContext.tsx +17 -0
- package/src/contexts/OpenPortalsContext.tsx +2 -0
- package/src/contexts/PortalScopeContext.tsx +2 -0
- package/src/hooks/mergeEventHandlers.ts +1 -1
- package/src/hooks/useHover.ts +30 -17
- package/src/hooks/useIndent.ts +5 -8
- package/src/hooks/useLabel.ts +2 -0
- package/src/hooks/useObjectURL.ts +5 -3
- package/src/hooks/usePlatform.ts +5 -3
- package/src/hooks/useTheme.ts +3 -1
- package/src/index.css +43 -10
- package/src/index.tsx +15 -7
- package/src/utils/classNames.ts +56 -9
- package/src/utils/combobox.ts +2 -0
- package/src/utils/editableBlockStyles.ts +2 -2
- package/src/utils/formatByteSize.ts +9 -0
- package/src/utils/inputs.ts +8 -6
- package/src/utils/sketchColor.ts +0 -34
- package/src/utils/withSeparatorElements.ts +1 -1
- package/tailwind.config.ts +1 -0
- package/src/components/FillInputField.tsx +0 -37
- package/src/components/FillPreviewBackground.tsx +0 -132
- package/src/components/GradientPicker.tsx +0 -88
- package/src/hooks/usePreservePanelSize.tsx +0 -183
- package/src/mediaQuery.ts +0 -13
- package/src/utils/getGradientBackground.tsx +0 -31
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { cssVarNames, cssVars } from "../theme";
|
|
3
|
+
import { cx } from "../utils/classNames";
|
|
3
4
|
import { Divider, DividerVertical } from "./Divider";
|
|
4
5
|
import { Spacer } from "./Spacer";
|
|
5
6
|
|
|
@@ -9,6 +10,9 @@ export interface BaseToolbarProps {
|
|
|
9
10
|
right?: React.ReactNode;
|
|
10
11
|
logo?: React.ReactNode;
|
|
11
12
|
showDivider?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
innerClassName?: string;
|
|
15
|
+
enableAbsoluteBreakpoint?: boolean;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
const toolbarStyle = {
|
|
@@ -16,51 +20,80 @@ const toolbarStyle = {
|
|
|
16
20
|
[cssVarNames.colors.inputBackground]: "transparent",
|
|
17
21
|
};
|
|
18
22
|
|
|
23
|
+
export function BaseToolbarContainer({
|
|
24
|
+
children,
|
|
25
|
+
showDivider = true,
|
|
26
|
+
className,
|
|
27
|
+
innerClassName,
|
|
28
|
+
enableAbsoluteBreakpoint = true,
|
|
29
|
+
}: {
|
|
30
|
+
children: React.ReactNode;
|
|
31
|
+
showDivider?: boolean;
|
|
32
|
+
className?: string;
|
|
33
|
+
innerClassName?: string;
|
|
34
|
+
enableAbsoluteBreakpoint?: boolean;
|
|
35
|
+
}) {
|
|
36
|
+
return (
|
|
37
|
+
<div className={cx("n-flex n-flex-col", className)} style={toolbarStyle}>
|
|
38
|
+
<div
|
|
39
|
+
className={cx(
|
|
40
|
+
"n-flex n-items-center n-bg-sidebar-background n-flex-none n-relative",
|
|
41
|
+
enableAbsoluteBreakpoint && "n-@container/toolbar",
|
|
42
|
+
innerClassName
|
|
43
|
+
)}
|
|
44
|
+
style={{
|
|
45
|
+
flex: `0 0 ${cssVars.spacing.toolbarHeight}`,
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
</div>
|
|
50
|
+
{showDivider && <Divider variant="strong" />}
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
19
55
|
export function BaseToolbar({
|
|
20
56
|
children,
|
|
21
57
|
left,
|
|
22
58
|
right,
|
|
23
59
|
logo,
|
|
24
60
|
showDivider = true,
|
|
61
|
+
className,
|
|
62
|
+
innerClassName,
|
|
63
|
+
enableAbsoluteBreakpoint = true,
|
|
25
64
|
}: BaseToolbarProps) {
|
|
26
65
|
return (
|
|
27
|
-
<
|
|
66
|
+
<BaseToolbarContainer
|
|
67
|
+
showDivider={showDivider}
|
|
68
|
+
className={className}
|
|
69
|
+
innerClassName={innerClassName}
|
|
70
|
+
enableAbsoluteBreakpoint={enableAbsoluteBreakpoint}
|
|
71
|
+
>
|
|
72
|
+
{logo && (
|
|
73
|
+
<>
|
|
74
|
+
{logo}
|
|
75
|
+
<DividerVertical />
|
|
76
|
+
</>
|
|
77
|
+
)}
|
|
78
|
+
<Spacer.Horizontal size={10} />
|
|
79
|
+
{left && (
|
|
80
|
+
<>
|
|
81
|
+
<div className="n-flex n-gap-toolbar-separator">{left}</div>
|
|
82
|
+
<Spacer.Horizontal size={10} />
|
|
83
|
+
</>
|
|
84
|
+
)}
|
|
28
85
|
<div
|
|
29
|
-
className=
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}}
|
|
86
|
+
className={
|
|
87
|
+
"n-flex n-items-center n-justify-center n-text-text-muted n-pointer-events-none @2xl/toolbar:n-absolute n-inset-0"
|
|
88
|
+
}
|
|
33
89
|
>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{logo}
|
|
37
|
-
<DividerVertical />
|
|
38
|
-
</>
|
|
39
|
-
)}
|
|
40
|
-
<Spacer.Horizontal size={10} />
|
|
41
|
-
{left && (
|
|
42
|
-
<>
|
|
43
|
-
<div className="flex gap-toolbar-separator">{left}</div>
|
|
44
|
-
<Spacer.Horizontal size={10} />
|
|
45
|
-
</>
|
|
46
|
-
)}
|
|
47
|
-
<div className="flex items-center justify-center text-text-muted pointer-events-none @2xl/toolbar:absolute inset-0">
|
|
48
|
-
<div
|
|
49
|
-
style={{
|
|
50
|
-
display: "flex",
|
|
51
|
-
alignItems: "center",
|
|
52
|
-
justifyContent: "center",
|
|
53
|
-
pointerEvents: "all",
|
|
54
|
-
}}
|
|
55
|
-
>
|
|
56
|
-
{children}
|
|
57
|
-
</div>
|
|
90
|
+
<div className="n-flex n-items-center n-justify-center n-pointer-events-auto">
|
|
91
|
+
{children}
|
|
58
92
|
</div>
|
|
59
|
-
<Spacer.Horizontal />
|
|
60
|
-
<Spacer.Horizontal size={10} />
|
|
61
|
-
<div className="flex gap-toolbar-separator">{right}</div>
|
|
62
93
|
</div>
|
|
63
|
-
|
|
64
|
-
|
|
94
|
+
<Spacer.Horizontal />
|
|
95
|
+
<Spacer.Horizontal size={10} />
|
|
96
|
+
<div className="n-flex n-gap-toolbar-separator">{right}</div>
|
|
97
|
+
</BaseToolbarContainer>
|
|
65
98
|
);
|
|
66
99
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { forwardRef } from "react";
|
|
2
4
|
|
|
3
5
|
import React from "react";
|
|
@@ -19,9 +21,9 @@ export const BreadcrumbText = forwardRef(function BreadcrumbText(
|
|
|
19
21
|
{...props}
|
|
20
22
|
variant="small"
|
|
21
23
|
className={cx(
|
|
22
|
-
"whitespace-pre leading-[15px] select-none",
|
|
24
|
+
"n-whitespace-pre n-leading-[15px] n-select-none",
|
|
23
25
|
onClick &&
|
|
24
|
-
"hover:text-breadcrumb-text-hover hover:cursor-pointer hover:whitespace-pre hover:select-none",
|
|
26
|
+
"hover:n-text-breadcrumb-text-hover hover:n-cursor-pointer hover:n-whitespace-pre hover:n-select-none",
|
|
25
27
|
className
|
|
26
28
|
)}
|
|
27
29
|
ref={ref}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import React, {
|
|
2
4
|
CSSProperties,
|
|
3
5
|
ForwardedRef,
|
|
@@ -12,7 +14,7 @@ import { Spacer } from "./Spacer";
|
|
|
12
14
|
import { Tooltip } from "./Tooltip";
|
|
13
15
|
import type { MenuItemIcon } from "./internal/Menu";
|
|
14
16
|
|
|
15
|
-
type ButtonVariant = "normal" | "thin" | "floating" | "none";
|
|
17
|
+
type ButtonVariant = "normal" | "thin" | "floating" | "none" | "ghost";
|
|
16
18
|
|
|
17
19
|
type ButtonSize = "small" | "normal" | "large" | "floating";
|
|
18
20
|
|
|
@@ -20,27 +22,29 @@ type ButtonColorScheme = "primary" | "secondary";
|
|
|
20
22
|
|
|
21
23
|
const colorSchemeStyles: Record<ButtonColorScheme | "default", string> = {
|
|
22
24
|
default:
|
|
23
|
-
"bg-button-background text-button-text hover:bg-button-background-hover active:bg-button-background-active",
|
|
24
|
-
primary:
|
|
25
|
+
"n-bg-button-background n-text-button-text hover:n-bg-button-background-hover active:n-bg-button-background-active",
|
|
26
|
+
primary:
|
|
27
|
+
"n-bg-primary n-text-white hover:n-bg-primary-light active:n-bg-primary",
|
|
25
28
|
secondary:
|
|
26
|
-
"bg-secondary text-white hover:bg-secondary-light active:bg-secondary",
|
|
29
|
+
"n-bg-secondary n-text-white hover:n-bg-secondary-light active:n-bg-secondary",
|
|
27
30
|
};
|
|
28
31
|
|
|
29
32
|
const variantStyles: Record<ButtonVariant, string> = {
|
|
30
33
|
normal: "",
|
|
31
34
|
floating:
|
|
32
|
-
"bg-floating-button text-text shadow-[0_1px_2px_rgba(0,0,0,0.1)] hover:opacity-80 active:opacity-90",
|
|
33
|
-
thin: "bg-transparent text-text hover:bg-input-background-light",
|
|
34
|
-
none: "bg-transparent text-text hover:bg-input-background-light",
|
|
35
|
+
"n-bg-floating-button n-text-text n-shadow-[0_1px_2px_rgba(0,0,0,0.1)] hover:n-opacity-80 active:n-opacity-90",
|
|
36
|
+
thin: "n-bg-transparent n-text-text hover:n-bg-input-background-light",
|
|
37
|
+
none: "n-bg-transparent n-text-text hover:n-bg-input-background-light",
|
|
38
|
+
ghost: "n-bg-transparent n-text-text hover:n-bg-input-background-light",
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
const sizeStyles: Record<ButtonSize | "thin" | "none", string> = {
|
|
38
|
-
small: "px-[2px] font-sans text-[10px] font-medium",
|
|
39
|
-
normal: "px-[6px] py-1 font-sans text-button font-medium",
|
|
40
|
-
large: "p-3 px-4 font-sans text-heading4 font-medium",
|
|
41
|
-
thin: "px-[1px] py-1 font-sans text-button font-medium",
|
|
42
|
-
floating: "px-1 py-0 font-sans text-[12px] font-medium",
|
|
43
|
-
none: "py-0 px-0",
|
|
42
|
+
small: "n-px-[2px] n-font-sans n-text-[10px] n-font-medium",
|
|
43
|
+
normal: "n-px-[6px] n-py-1 n-font-sans n-text-button n-font-medium",
|
|
44
|
+
large: "n-p-3 n-px-4 n-font-sans n-text-heading4 n-font-medium",
|
|
45
|
+
thin: "n-px-[1px] n-py-1 n-font-sans n-text-button n-font-medium",
|
|
46
|
+
floating: "n-px-1 n-py-0 n-font-sans n-text-[12px] n-font-medium",
|
|
47
|
+
none: "n-py-0 n-px-0",
|
|
44
48
|
};
|
|
45
49
|
|
|
46
50
|
export interface ButtonProps
|
|
@@ -97,11 +101,12 @@ export const Button = forwardRef(function Button(
|
|
|
97
101
|
const colorScheme = colorSchemeProp ?? "default";
|
|
98
102
|
|
|
99
103
|
const baseClassName = cx(
|
|
100
|
-
"no-underline leading-[1] relative
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
"n-no-underline n-leading-[1] n-relative n-outline-none n-select-none n-text-left n-rounded n-flex n-items-center n-justify-center [&>*]:n-pointer-events-none n-[-webkit-app-region:no-drag] focus:n-ring-2 focus:n-ring-primary focus:n-shadow-[0_0_0_1px_var(--n-popover-background)_inset] n-transition-all",
|
|
105
|
+
variant === "ghost" ? "n-border" : "n-border-0",
|
|
106
|
+
disabled ? "n-opacity-25" : "",
|
|
107
|
+
!className?.includes("flex") ? "n-flex-none" : "",
|
|
103
108
|
active
|
|
104
|
-
? "bg-button-background-active text-button-text-active hover:bg-button-background-active-hover"
|
|
109
|
+
? "n-bg-button-background-active n-text-button-text-active hover:n-bg-button-background-active-hover"
|
|
105
110
|
: variantStyles[variant],
|
|
106
111
|
sizeStyles[
|
|
107
112
|
variant === "thin"
|
|
@@ -112,9 +117,11 @@ export const Button = forwardRef(function Button(
|
|
|
112
117
|
? "none"
|
|
113
118
|
: size
|
|
114
119
|
],
|
|
115
|
-
variant === "normal" && (children ? "min-w-[31px]" : "min-w-[27px]"),
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
variant === "normal" && (children ? "n-min-w-[31px]" : "n-min-w-[27px]"),
|
|
121
|
+
variant === "ghost"
|
|
122
|
+
? "n-border-solid n-border-input-background hover:n-bg-input-background-light"
|
|
123
|
+
: colorSchemeStyles[colorScheme],
|
|
124
|
+
!children && (icon || iconRight) && !(icon && iconRight) && "n-w-[27px]"
|
|
118
125
|
);
|
|
119
126
|
|
|
120
127
|
const buttonClassName = useMemo(() => {
|
|
@@ -140,7 +147,7 @@ export const Button = forwardRef(function Button(
|
|
|
140
147
|
{...rest}
|
|
141
148
|
>
|
|
142
149
|
<span
|
|
143
|
-
className="min-h-[19px] flex items-center flex-1 justify-center leading-[15px]"
|
|
150
|
+
className="n-min-h-[19px] n-flex n-items-center n-flex-1 n-justify-center n-leading-[15px]"
|
|
144
151
|
style={contentStyle}
|
|
145
152
|
>
|
|
146
153
|
{icon && renderIcon(icon)}
|
|
@@ -160,5 +167,3 @@ export const Button = forwardRef(function Button(
|
|
|
160
167
|
buttonElement
|
|
161
168
|
);
|
|
162
169
|
});
|
|
163
|
-
|
|
164
|
-
export default Button;
|
|
@@ -8,9 +8,9 @@ interface CheckboxProps
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const colorSchemeStyles = {
|
|
11
|
-
normal: "text-text-subtle",
|
|
12
|
-
primary: "text-primary",
|
|
13
|
-
secondary: "text-secondary",
|
|
11
|
+
normal: "n-text-text-subtle",
|
|
12
|
+
primary: "n-text-primary",
|
|
13
|
+
secondary: "n-text-secondary",
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export const Checkbox = React.memo(
|
|
@@ -22,7 +22,7 @@ export const Checkbox = React.memo(
|
|
|
22
22
|
return (
|
|
23
23
|
<div
|
|
24
24
|
className={cx(
|
|
25
|
-
"flex-none relative inline-flex w-[19px] h-[19px]",
|
|
25
|
+
"n-flex-none n-relative n-inline-flex n-w-[19px] n-h-[19px]",
|
|
26
26
|
colorSchemeStyles[colorScheme],
|
|
27
27
|
className
|
|
28
28
|
)}
|
|
@@ -31,42 +31,13 @@ export const Checkbox = React.memo(
|
|
|
31
31
|
<input
|
|
32
32
|
ref={ref}
|
|
33
33
|
type="checkbox"
|
|
34
|
-
className={`
|
|
35
|
-
w-full
|
|
36
|
-
h-full
|
|
37
|
-
peer
|
|
38
|
-
appearance-none
|
|
39
|
-
m-0
|
|
40
|
-
rounded
|
|
41
|
-
bg-input-background
|
|
42
|
-
border
|
|
43
|
-
border-divider
|
|
44
|
-
disabled:opacity-50
|
|
45
|
-
cursor-pointer
|
|
46
|
-
disabled:cursor-not-allowed
|
|
47
|
-
focus:ring-2
|
|
48
|
-
focus:ring-primary
|
|
49
|
-
focus:ring-offset-1
|
|
50
|
-
focus:z-interactable
|
|
51
|
-
transition-all
|
|
52
|
-
`}
|
|
34
|
+
className={`n-w-full n-h-full n-peer n-appearance-none n-m-0 n-rounded n-bg-input-background n-border n-border-divider disabled:n-opacity-50 n-cursor-pointer disabled:n-cursor-not-allowed focus:n-ring-2 focus:n-ring-primary focus:n-ring-offset-1 focus:n-z-interactable n-transition-all`}
|
|
53
35
|
aria-checked={props.checked}
|
|
54
36
|
{...props}
|
|
55
37
|
id={id}
|
|
56
38
|
/>
|
|
57
39
|
<svg
|
|
58
|
-
className={`
|
|
59
|
-
absolute
|
|
60
|
-
inset-0
|
|
61
|
-
h-input-height
|
|
62
|
-
w-input-height
|
|
63
|
-
pointer-events-none
|
|
64
|
-
stroke-white
|
|
65
|
-
opacity-0
|
|
66
|
-
peer-checked:opacity-100
|
|
67
|
-
z-label
|
|
68
|
-
stroke-[1.3px]
|
|
69
|
-
`}
|
|
40
|
+
className={`n-absolute n-inset-0 n-h-input-height n-w-input-height n-pointer-events-none n-stroke-white n-opacity-0 peer-checked:n-opacity-100 n-z-label stroke-[1.3px]`}
|
|
70
41
|
viewBox="0 0 16 16"
|
|
71
42
|
fill="none"
|
|
72
43
|
xmlns="http://www.w3.org/2000/svg"
|
package/src/components/Chip.tsx
CHANGED
|
@@ -1,67 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { Cross1Icon, PlusIcon } from "@noya-app/noya-icons";
|
|
2
4
|
import React, { forwardRef, memo } from "react";
|
|
3
5
|
import { useHover } from "../hooks/useHover";
|
|
4
6
|
import { cssVars } from "../theme";
|
|
5
7
|
import { cx } from "../utils/classNames";
|
|
6
8
|
|
|
7
|
-
type ChipColorScheme = "primary" | "secondary" | "error";
|
|
8
|
-
type ChipSize = "small" | "medium" | "large";
|
|
9
|
+
type ChipColorScheme = "primary" | "secondary" | "info" | "error";
|
|
10
|
+
type ChipSize = "small" | "medium" | "large" | "xl";
|
|
9
11
|
type ChipVariant = "solid" | "outlined" | "ghost";
|
|
10
12
|
|
|
11
13
|
// Hoisted constants for styles
|
|
12
14
|
const BASE_STYLES =
|
|
13
|
-
"inline-flex items-center whitespace-pre rounded select-none leading-[15px]";
|
|
15
|
+
"n-inline-flex n-items-center n-whitespace-pre n-rounded n-select-none n-leading-[15px]";
|
|
14
16
|
|
|
15
17
|
const SIZE_STYLES = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
xl: "n-text-[12px] n-p-[6px_12px]",
|
|
19
|
+
large: "n-text-[11px] n-p-[4px_8px]",
|
|
20
|
+
medium: "n-text-[10px] n-p-[2px_6px]",
|
|
21
|
+
small: "n-text-[9px] n-p-[0px_4px]",
|
|
19
22
|
} as const;
|
|
20
23
|
|
|
21
24
|
const SHADOW_STYLES = {
|
|
22
|
-
primary: "shadow-[0_0_0_1px_var(--n-chip-primary-shadow)_inset]",
|
|
23
|
-
secondary: "shadow-[0_0_0_1px_var(--n-chip-secondary-shadow)_inset]",
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
primary: "n-shadow-[0_0_0_1px_var(--n-chip-primary-shadow)_inset]",
|
|
26
|
+
secondary: "n-shadow-[0_0_0_1px_var(--n-chip-secondary-shadow)_inset]",
|
|
27
|
+
info: "n-shadow-[0_0_0_1px_var(--n-chip-default-shadow)_inset]",
|
|
28
|
+
error: "n-shadow-[0_0_0_1px_var(--n-chip-error-shadow)_inset]",
|
|
29
|
+
default: "n-shadow-[0_0_0_1px_var(--n-chip-default-shadow)_inset]",
|
|
26
30
|
} as const;
|
|
27
31
|
|
|
28
32
|
const COLOR_STYLES = {
|
|
29
33
|
primary: {
|
|
30
|
-
text: "text-primary",
|
|
31
|
-
bg: "bg-primary-pastel",
|
|
32
|
-
subtle: "bg-[var(--n-chip-primary-bg)]",
|
|
34
|
+
text: "n-text-primary",
|
|
35
|
+
bg: "n-bg-primary-pastel",
|
|
36
|
+
subtle: "n-bg-[var(--n-chip-primary-bg)]",
|
|
33
37
|
},
|
|
34
38
|
secondary: {
|
|
35
|
-
text: "text-secondary",
|
|
36
|
-
bg: "bg-secondary-pastel",
|
|
37
|
-
subtle: "bg-[var(--n-chip-secondary-bg)]",
|
|
39
|
+
text: "n-text-secondary",
|
|
40
|
+
bg: "n-bg-secondary-pastel",
|
|
41
|
+
subtle: "n-bg-[var(--n-chip-secondary-bg)]",
|
|
42
|
+
},
|
|
43
|
+
info: {
|
|
44
|
+
text: "n-text-[#4071e8]",
|
|
45
|
+
bg: "n-bg-[#dce8ff]",
|
|
46
|
+
subtle: "n-bg-[var(--n-banner-info-border)]",
|
|
38
47
|
},
|
|
39
48
|
error: {
|
|
40
|
-
text: "text-text",
|
|
41
|
-
bg: "bg-[rgb(255,219,219)]",
|
|
42
|
-
subtle: "bg-[var(--n-chip-error-bg)]",
|
|
49
|
+
text: "n-text-text",
|
|
50
|
+
bg: "n-bg-[rgb(255,219,219)]",
|
|
51
|
+
subtle: "n-bg-[var(--n-chip-error-bg)]",
|
|
43
52
|
},
|
|
44
53
|
default: {
|
|
45
|
-
text: "text-text",
|
|
46
|
-
bg: "bg-input-background",
|
|
47
|
-
subtle: "bg-[var(--n-chip-default-bg)]",
|
|
54
|
+
text: "n-text-text",
|
|
55
|
+
bg: "n-bg-input-background",
|
|
56
|
+
subtle: "n-bg-[var(--n-chip-default-bg)]",
|
|
48
57
|
},
|
|
49
58
|
} as const;
|
|
50
59
|
|
|
51
|
-
const ICON_BASE_STYLES =
|
|
60
|
+
const ICON_BASE_STYLES =
|
|
61
|
+
"n-relative n-opacity-50 n-cursor-pointer hover:n-opacity-85";
|
|
52
62
|
|
|
53
63
|
const ICON_SIZE_STYLES = {
|
|
64
|
+
xl: {
|
|
65
|
+
add: "n-ml-[-2px] n-mr-[2px] -n-top-[1px] n-scale-[0.75]",
|
|
66
|
+
delete: "n-mr-[-2px] n-ml-[2px] n-scale-[0.75]",
|
|
67
|
+
},
|
|
54
68
|
large: {
|
|
55
|
-
add: "ml-[-2px] mr-[2px] -top-[1px] scale-[0.75]",
|
|
56
|
-
delete: "mr-[-2px] ml-[2px] scale-[0.75]",
|
|
69
|
+
add: "n-ml-[-2px] n-mr-[2px] -n-top-[1px] n-scale-[0.75]",
|
|
70
|
+
delete: "n-mr-[-2px] n-ml-[2px] n-scale-[0.75]",
|
|
57
71
|
},
|
|
58
72
|
medium: {
|
|
59
|
-
add: "ml-[-2px] mr-[-2px] scale-[0.60]",
|
|
60
|
-
delete: "mr-[-2px] scale-[0.60]",
|
|
73
|
+
add: "n-ml-[-2px] n-mr-[-2px] n-scale-[0.60]",
|
|
74
|
+
delete: "n-mr-[-2px] n-scale-[0.60]",
|
|
61
75
|
},
|
|
62
76
|
small: {
|
|
63
|
-
add: "ml-[-2px] mr-[-2px] scale-[0.60]",
|
|
64
|
-
delete: "mr-[-2px] scale-[0.60]",
|
|
77
|
+
add: "n-ml-[-2px] n-mr-[-2px] n-scale-[0.60]",
|
|
78
|
+
delete: "n-mr-[-2px] n-scale-[0.60]",
|
|
65
79
|
},
|
|
66
80
|
} as const;
|
|
67
81
|
|
|
@@ -121,16 +135,16 @@ export const Chip = memo(
|
|
|
121
135
|
variant === "solid"
|
|
122
136
|
? `${colors.text} ${colors.bg}`
|
|
123
137
|
: variant === "outlined"
|
|
124
|
-
? `${colors.text} bg-transparent ${SHADOW_STYLES[colorScheme ?? "default"]} hover:${colors.subtle} hover:shadow-none`
|
|
138
|
+
? `${colors.text} n-bg-transparent ${SHADOW_STYLES[colorScheme ?? "default"]} hover:${colors.subtle} hover:n-shadow-none`
|
|
125
139
|
: "";
|
|
126
140
|
|
|
127
141
|
const chipClasses = cx(
|
|
128
142
|
BASE_STYLES,
|
|
129
143
|
SIZE_STYLES[size],
|
|
130
|
-
monospace && "font-mono",
|
|
144
|
+
monospace && "n-font-mono",
|
|
131
145
|
variantClasses,
|
|
132
|
-
isInteractive && "cursor-pointer hover:opacity-85",
|
|
133
|
-
disabled && "opacity-50",
|
|
146
|
+
isInteractive && "n-cursor-pointer hover:n-opacity-85",
|
|
147
|
+
disabled && "n-opacity-50",
|
|
134
148
|
className
|
|
135
149
|
);
|
|
136
150
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Size } from "@noya-app/noya-geometry";
|
|
1
4
|
import { forwardRefGeneric } from "@noya-app/react-utils";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { Grid } from "
|
|
4
|
-
import { MenuItem } from "
|
|
5
|
-
import {
|
|
6
|
-
ListView,
|
|
7
|
-
ListViewRootProps,
|
|
8
|
-
ListViewRowProps,
|
|
9
|
-
} from "../components/ListView";
|
|
5
|
+
import React, { CSSProperties } from "react";
|
|
6
|
+
import { Grid } from "./Grid";
|
|
7
|
+
import { MenuItem } from "./internal/Menu";
|
|
10
8
|
import { List } from "./List";
|
|
9
|
+
import { ListView } from "./ListView";
|
|
10
|
+
import { ListViewRootProps } from "./listView/ListViewRoot";
|
|
11
|
+
import { ListViewRowProps } from "./listView/ListViewRow";
|
|
11
12
|
import { SharedDragProps } from "./sorting/DragRegistration";
|
|
12
13
|
|
|
13
14
|
export type CollectionViewType = "grid" | "list";
|
|
@@ -33,8 +34,10 @@ export type CollectionRenderActionProps<T> = {
|
|
|
33
34
|
export interface CollectionProps<T, M extends string = string> {
|
|
34
35
|
className?: string;
|
|
35
36
|
items: T[];
|
|
37
|
+
virtualized?: Size;
|
|
36
38
|
getId: (item: T) => string;
|
|
37
39
|
getName: (item: T) => string;
|
|
40
|
+
getHref?: (item: T) => string;
|
|
38
41
|
getExpanded?: (item: T) => boolean | undefined;
|
|
39
42
|
getPlaceholder?: (item: T) => string;
|
|
40
43
|
/**
|
|
@@ -59,12 +62,16 @@ export interface CollectionProps<T, M extends string = string> {
|
|
|
59
62
|
| "menu"
|
|
60
63
|
| ((props: CollectionRenderActionProps<T>) => React.ReactNode);
|
|
61
64
|
renderDetail?: (item: T, selected: boolean) => React.ReactNode;
|
|
65
|
+
/** Optional right-side content renderer for each item */
|
|
66
|
+
renderRight?: (item: T, selected: boolean) => React.ReactNode;
|
|
62
67
|
/** Callback when selection changes. If not provided, selection will be disabled. */
|
|
63
68
|
onSelectionChange?: (
|
|
64
69
|
selectedItemIds: string[],
|
|
65
70
|
event?: ListView.ClickInfo
|
|
66
71
|
) => void;
|
|
67
72
|
scrollable?: boolean;
|
|
73
|
+
itemStyle?: CSSProperties;
|
|
74
|
+
itemClassName?: string;
|
|
68
75
|
itemRoleDescription?: string;
|
|
69
76
|
/** Position of the detail content. Defaults to 'end'. */
|
|
70
77
|
detailPosition?: "end" | "below";
|
|
@@ -79,18 +86,19 @@ export interface CollectionProps<T, M extends string = string> {
|
|
|
79
86
|
/** For testing: Override the drop indicator state with a specific item ID */
|
|
80
87
|
testShowDropIndicatorId?: string;
|
|
81
88
|
setExpanded?: (item: T, expanded: boolean) => void;
|
|
82
|
-
acceptsDrop?: ListViewRootProps["acceptsDrop"];
|
|
83
|
-
onMoveItem?: ListViewRootProps["onMoveItem"];
|
|
84
|
-
getDropTargetParentIndex?: ListViewRootProps["getDropTargetParentIndex"];
|
|
89
|
+
acceptsDrop?: ListViewRootProps<T>["acceptsDrop"];
|
|
90
|
+
onMoveItem?: ListViewRootProps<T>["onMoveItem"];
|
|
91
|
+
getDropTargetParentIndex?: ListViewRootProps<T>["getDropTargetParentIndex"];
|
|
85
92
|
getDepth?: (item: T) => number;
|
|
86
93
|
onFilesDrop?: (event: React.DragEvent<Element>) => void;
|
|
87
94
|
getRenamable?: (item: T) => boolean;
|
|
88
95
|
/** Currently selected file IDs */
|
|
89
96
|
selectedIds?: string[];
|
|
90
97
|
viewType?: CollectionViewType;
|
|
98
|
+
onClick?: () => void;
|
|
91
99
|
onClickItem?: (itemId: string) => void;
|
|
92
100
|
onDoubleClickItem?: (itemId: string) => void;
|
|
93
|
-
renderEmptyState?: () => React.ReactElement
|
|
101
|
+
renderEmptyState?: () => React.ReactElement<any>;
|
|
94
102
|
/** @default false */
|
|
95
103
|
sortable?: boolean;
|
|
96
104
|
dragIndicatorStyle?: ListViewRowProps<M>["dragIndicatorStyle"];
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import { getContrastColorForBackground } from "@noya-app/noya-color";
|
|
2
|
+
import { CheckIcon } from "@noya-app/noya-icons";
|
|
1
3
|
import React, { forwardRef } from "react";
|
|
2
|
-
import { cssVars } from "../theme";
|
|
3
4
|
|
|
4
|
-
export type ColorSwatchSize =
|
|
5
|
+
export type ColorSwatchSize =
|
|
6
|
+
| "xxsmall"
|
|
7
|
+
| "xsmall"
|
|
8
|
+
| "small"
|
|
9
|
+
| "medium"
|
|
10
|
+
| "large";
|
|
5
11
|
|
|
6
|
-
export const colorSwatchSizeMap = {
|
|
12
|
+
export const colorSwatchSizeMap: Record<ColorSwatchSize, number> = {
|
|
13
|
+
xxsmall: 15,
|
|
7
14
|
xsmall: 21,
|
|
8
15
|
small: 27,
|
|
9
16
|
medium: 36,
|
|
@@ -14,32 +21,45 @@ type ColorSwatchProps = {
|
|
|
14
21
|
color: string;
|
|
15
22
|
size?: ColorSwatchSize;
|
|
16
23
|
checked?: boolean;
|
|
24
|
+
as?: React.ElementType;
|
|
17
25
|
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
18
26
|
|
|
19
27
|
export const ColorSwatch = forwardRef(function ColorSwatch(
|
|
20
|
-
{
|
|
28
|
+
{
|
|
29
|
+
color,
|
|
30
|
+
size = "small",
|
|
31
|
+
checked,
|
|
32
|
+
style,
|
|
33
|
+
as: Component = "button",
|
|
34
|
+
...props
|
|
35
|
+
}: ColorSwatchProps,
|
|
21
36
|
ref: React.ForwardedRef<HTMLButtonElement>
|
|
22
37
|
) {
|
|
23
38
|
const sizePx = colorSwatchSizeMap[size];
|
|
39
|
+
const checkedColor = getContrastColorForBackground(color);
|
|
24
40
|
|
|
25
41
|
return (
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
: "1px solid rgba(0,0,0,0.1)",
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
<div className="n-relative" style={{ width: sizePx, height: sizePx }}>
|
|
43
|
+
<Component
|
|
44
|
+
{...props}
|
|
45
|
+
ref={ref}
|
|
46
|
+
style={{
|
|
47
|
+
display: "inline-block",
|
|
48
|
+
background: color,
|
|
49
|
+
width: sizePx,
|
|
50
|
+
height: sizePx,
|
|
51
|
+
borderRadius: "4px",
|
|
52
|
+
outline: "1px solid rgba(0,0,0,0.1)",
|
|
53
|
+
outlineOffset: -1,
|
|
54
|
+
...style,
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
{checked && (
|
|
58
|
+
<CheckIcon
|
|
59
|
+
color={checkedColor}
|
|
60
|
+
className="n-absolute n-top-1/2 n-left-1/2 -n-translate-x-1/2 -n-translate-y-1/2"
|
|
61
|
+
/>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
44
64
|
);
|
|
45
65
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
|
|
2
4
|
import React, { useMemo } from "react";
|
|
3
5
|
import { cx } from "../utils/classNames";
|
|
4
6
|
import {
|
|
@@ -52,14 +54,14 @@ export function ColorSwatchControl(props: ColorSwatchControlProps) {
|
|
|
52
54
|
{options.map((option) => {
|
|
53
55
|
const item = (
|
|
54
56
|
<ColorSwatch
|
|
55
|
-
key={option as string}
|
|
57
|
+
key={`${option as string}-color-swatch`}
|
|
56
58
|
color={option as string}
|
|
57
59
|
size={size}
|
|
58
60
|
onFocus={onFocus}
|
|
59
61
|
onBlur={onBlur}
|
|
60
62
|
disabled={disabled}
|
|
61
63
|
// TODO: decide on "checked" visual treatment
|
|
62
|
-
className={cx(readOnly ? "cursor-default" : "cursor-pointer")}
|
|
64
|
+
className={cx(readOnly ? "n-cursor-default" : "n-cursor-pointer")}
|
|
63
65
|
checked={value === option}
|
|
64
66
|
/>
|
|
65
67
|
);
|
|
@@ -67,7 +69,7 @@ export function ColorSwatchControl(props: ColorSwatchControlProps) {
|
|
|
67
69
|
<ToggleGroupPrimitive.Item
|
|
68
70
|
asChild
|
|
69
71
|
value={option as string}
|
|
70
|
-
key={option as string}
|
|
72
|
+
key={`${option as string}-toggle-group-item`}
|
|
71
73
|
disabled={readOnly}
|
|
72
74
|
>
|
|
73
75
|
{item}
|
|
@@ -81,7 +83,7 @@ export function ColorSwatchControl(props: ColorSwatchControlProps) {
|
|
|
81
83
|
type="single"
|
|
82
84
|
value={value as string}
|
|
83
85
|
onValueChange={onValueChange}
|
|
84
|
-
className="w-full"
|
|
86
|
+
className="n-w-full"
|
|
85
87
|
disabled={readOnly}
|
|
86
88
|
>
|
|
87
89
|
{content}
|