@noya-app/noya-designsystem 0.1.49 → 0.1.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +19 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +169 -205
  5. package/dist/index.d.ts +169 -205
  6. package/dist/index.js +5092 -13463
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +3501 -11912
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +9 -9
  11. package/src/components/ActionMenu.tsx +4 -2
  12. package/src/components/Avatar.tsx +2 -2
  13. package/src/components/Banner.tsx +29 -0
  14. package/src/components/Button.tsx +2 -2
  15. package/src/components/Chip.tsx +8 -8
  16. package/src/components/Collection.tsx +18 -4
  17. package/src/components/ComboboxMenu.tsx +10 -1
  18. package/src/components/Dialog.tsx +2 -2
  19. package/src/components/FillInputField.tsx +1 -1
  20. package/src/components/Grid.tsx +12 -11
  21. package/src/components/Label.tsx +11 -6
  22. package/src/components/LabeledField.tsx +6 -1
  23. package/src/components/List.tsx +30 -24
  24. package/src/components/ListView.tsx +10 -5
  25. package/src/components/MediaThumbnail.tsx +31 -9
  26. package/src/components/Popover.tsx +9 -6
  27. package/src/components/SearchCompletionMenu.tsx +12 -12
  28. package/src/components/Section.tsx +172 -0
  29. package/src/components/SegmentedControl.tsx +1 -1
  30. package/src/components/SelectMenu.tsx +1 -1
  31. package/src/components/Slider.tsx +1 -1
  32. package/src/components/Sortable.tsx +124 -22
  33. package/src/components/Toolbar.tsx +22 -10
  34. package/src/components/UserPointer.tsx +1 -1
  35. package/src/components/ai-assistant/AIAssistantLayout.tsx +102 -0
  36. package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +71 -0
  37. package/src/components/file-explorer/FileExplorerLayout.tsx +81 -0
  38. package/src/components/internal/Menu.tsx +12 -7
  39. package/src/components/internal/TextInput.tsx +7 -2
  40. package/src/components/pipeline/PipelineResultLayout.tsx +32 -0
  41. package/src/index.css +125 -118
  42. package/src/index.tsx +7 -0
  43. package/src/theme/index.ts +1 -1
  44. package/src/utils/classNames.ts +28 -3
  45. package/src/utils/combobox.ts +18 -13
  46. package/src/utils/moveTreeItem.ts +99 -0
  47. package/tailwind.config.ts +2 -239
  48. package/tailwind.d.ts +1 -1
  49. package/tsup.config.ts +0 -3
@@ -0,0 +1,71 @@
1
+ import { cssVars } from "../../theme";
2
+
3
+ import { ChatBubbleWithDotsIcon } from "@noya-app/noya-icons";
4
+ import React from "react";
5
+ import { INPUT_HEIGHT } from "../../theme";
6
+ import { colorFromString } from "../../utils/colorFromString";
7
+ import { Avatar, AvatarProps, AvatarStack } from "../Avatar";
8
+ import Button from "../Button";
9
+ import { Spacer } from "../Spacer";
10
+ import { Small } from "../Text";
11
+ import { Tooltip } from "../Tooltip";
12
+
13
+ export const UserAvatar = ({ userId, name, image }: AvatarProps) => (
14
+ <Tooltip
15
+ key={userId}
16
+ content={
17
+ <div className="flex flex-col">
18
+ <Small>{name}</Small>
19
+ </div>
20
+ }
21
+ >
22
+ <Avatar size={INPUT_HEIGHT} userId={userId} name={name} image={image} />
23
+ </Tooltip>
24
+ );
25
+
26
+ type ConnectedUsersMenuLayoutProps = {
27
+ renderUsers: () => React.ReactNode;
28
+ currentUserId?: string;
29
+ launchAIAssistant?: () => void;
30
+ isAssistantOpen?: boolean;
31
+ };
32
+
33
+ export const ConnectedUsersMenuLayout = ({
34
+ renderUsers,
35
+ currentUserId,
36
+ launchAIAssistant,
37
+ isAssistantOpen,
38
+ }: ConnectedUsersMenuLayoutProps) => {
39
+ return (
40
+ <div className="flex gap-1.5">
41
+ <AvatarStack size={INPUT_HEIGHT}>{renderUsers()}</AvatarStack>
42
+
43
+ {/* AI Assistant Avatar */}
44
+ {launchAIAssistant && (
45
+ <Tooltip
46
+ content={
47
+ <div className="flex flex-col">
48
+ <Small>AI Assistant</Small>
49
+ </div>
50
+ }
51
+ >
52
+ <Button
53
+ variant={isAssistantOpen ? "secondary" : undefined}
54
+ onClick={launchAIAssistant}
55
+ style={{
56
+ backgroundColor: isAssistantOpen
57
+ ? colorFromString(currentUserId ?? "")
58
+ : undefined,
59
+ }}
60
+ >
61
+ AI
62
+ <Spacer.Horizontal size={8} />
63
+ <ChatBubbleWithDotsIcon
64
+ color={isAssistantOpen ? undefined : cssVars.colors.icon}
65
+ />
66
+ </Button>
67
+ </Tooltip>
68
+ )}
69
+ </div>
70
+ );
71
+ };
@@ -0,0 +1,81 @@
1
+ import {
2
+ Banner,
3
+ BannerProps,
4
+ IconButton,
5
+ Section,
6
+ SectionProps,
7
+ } from "@noya-app/noya-designsystem";
8
+ import { forwardRefGeneric } from "@noya-app/react-utils";
9
+ import React from "react";
10
+ import { cx } from "../../utils/classNames";
11
+ import {
12
+ Collection,
13
+ CollectionItemSize,
14
+ CollectionProps,
15
+ CollectionRef,
16
+ } from "../Collection";
17
+
18
+ export const FileExplorerLayout = ({
19
+ children,
20
+ className,
21
+ ...props
22
+ }: SectionProps) => (
23
+ <Section className={cx(className, "px-3 flex-1")} {...props}>
24
+ {children}
25
+ </Section>
26
+ );
27
+
28
+ export const FileExplorerUploadButton = ({
29
+ showUploadButton,
30
+ onUpload,
31
+ children,
32
+ }: {
33
+ showUploadButton?: boolean;
34
+ onUpload?: () => void;
35
+ children?: React.ReactNode;
36
+ }) => (
37
+ <div className="flex items-center gap-2">
38
+ {showUploadButton && (
39
+ <IconButton
40
+ iconName="UploadIcon"
41
+ onClick={onUpload}
42
+ aria-label="Upload media"
43
+ tooltip="Upload media"
44
+ />
45
+ )}
46
+ {children}
47
+ </div>
48
+ );
49
+
50
+ export const FileExplorerCollection = forwardRefGeneric(
51
+ function FileExplorerCollection<T, M extends string = string>(
52
+ { ...props }: CollectionProps<T, M>,
53
+ ref: React.ForwardedRef<CollectionRef>
54
+ ) {
55
+ return <Collection<T, M> ref={ref} className="-mx-3 flex-1" {...props} />;
56
+ }
57
+ );
58
+
59
+ export const FileExplorerDetail = ({
60
+ selected,
61
+ size,
62
+ children,
63
+ }: {
64
+ selected: boolean;
65
+ children: React.ReactNode;
66
+ size?: CollectionItemSize;
67
+ }) => (
68
+ <span
69
+ className={cx(
70
+ size === "small" ? "text-list-small" : "text-sm",
71
+ selected ? "text-primary" : "text-text-muted"
72
+ )}
73
+ >
74
+ {children}
75
+ </span>
76
+ );
77
+
78
+ export const FileExplorerEmptyState = ({
79
+ label = "No files",
80
+ ...props
81
+ }: BannerProps) => <Banner label={label} className="mx-3" {...props} />;
@@ -1,7 +1,7 @@
1
1
  import { getShortcutDisplayParts } from "@noya-app/noya-keymap";
2
2
  import React, { memo, ReactNode } from "react";
3
3
  import { useDesignSystemConfiguration } from "../../contexts/DesignSystemConfiguration";
4
- import { cx } from "../../utils/classNames";
4
+ import { cx, mergeConflictingClassNames } from "../../utils/classNames";
5
5
  import { IScoredItem } from "../../utils/fuzzyScorer";
6
6
  import withSeparatorElements from "../../utils/withSeparatorElements";
7
7
  import { IconName } from "../Icons";
@@ -270,12 +270,17 @@ export const SectionHeader = memo(function SectionHeader({
270
270
  return (
271
271
  <span
272
272
  id={id}
273
- className={cx(
274
- variant === "label"
275
- ? `text-label ${textStyles.label} !font-bold text-text-disabled`
276
- : "font-sans text-heading5 font-normal",
277
- "bg-listview-raised-background flex items-center py-1.5 px-3",
278
- isFirst && "-mt-1"
273
+ className={mergeConflictingClassNames(
274
+ [
275
+ variant === "label"
276
+ ? `text-label ${textStyles.label} font-bold text-text-disabled`
277
+ : "font-sans text-heading5 font-normal",
278
+ "bg-listview-raised-background flex items-center py-1.5 px-3",
279
+ isFirst && "-mt-1",
280
+ ],
281
+ {
282
+ categories: ["font"],
283
+ }
279
284
  )}
280
285
  >
281
286
  {indented && (
@@ -126,6 +126,8 @@ type SubmittableProps = Props & {
126
126
  onSubmit: (value: string) => void;
127
127
  allowSubmittingWithSameValue?: boolean;
128
128
  submitAutomaticallyAfterDelay?: number;
129
+ /** @default true */
130
+ submitOnBlur?: boolean;
129
131
  };
130
132
 
131
133
  const SubmittableTextInput = forwardRef(function SubmittableTextInput(
@@ -138,6 +140,7 @@ const SubmittableTextInput = forwardRef(function SubmittableTextInput(
138
140
  onFocusCapture,
139
141
  allowSubmittingWithSameValue = false,
140
142
  submitAutomaticallyAfterDelay,
143
+ submitOnBlur = true,
141
144
  ...rest
142
145
  }: SubmittableProps,
143
146
  forwardedRef: ForwardedRef<HTMLInputElement>
@@ -218,9 +221,11 @@ const SubmittableTextInput = forwardRef(function SubmittableTextInput(
218
221
 
219
222
  onFocusChange?.(false);
220
223
 
221
- handleSubmit();
224
+ if (submitOnBlur) {
225
+ handleSubmit();
226
+ }
222
227
  },
223
- [onBlur, onFocusChange, handleSubmit]
228
+ [onBlur, onFocusChange, handleSubmit, submitOnBlur]
224
229
  );
225
230
 
226
231
  const handleFocusCapture = useCallback(
@@ -0,0 +1,32 @@
1
+ import { Link1Icon } from "@noya-app/noya-icons";
2
+ import React from "react";
3
+ import { DividerVertical } from "../Divider";
4
+ import { Small } from "../Text";
5
+
6
+ export const PipelineResultLink = ({ url }: { url: string }) => {
7
+ return (
8
+ <div className="flex flex-col gap-0.5">
9
+ {/* <Label position="start">{name}</Label> */}
10
+ <a
11
+ href={url}
12
+ target="_blank"
13
+ rel="noopener noreferrer"
14
+ className="flex text-primary hover:opacity-80 border border-divider rounded-md"
15
+ >
16
+ <div className="flex gap-1 items-center p-2">
17
+ <Link1Icon className="w-[15px] h-[15px] flex-shrink-0" />
18
+ </div>
19
+ <DividerVertical />
20
+ <Small className="truncate p-2 flex-1">{url}</Small>
21
+ </a>
22
+ </div>
23
+ );
24
+ };
25
+
26
+ export const PipelineResultLayout = ({
27
+ children,
28
+ }: {
29
+ children: React.ReactNode;
30
+ }) => {
31
+ return <div className="flex flex-col gap-2">{children}</div>;
32
+ };
package/src/index.css CHANGED
@@ -3,125 +3,132 @@
3
3
  @tailwind utilities;
4
4
 
5
5
  :root {
6
- --logo-fill: rgb(150, 152, 172);
7
- --logo-highlight: rgb(150, 152, 172);
8
- --background: rgb(255, 255, 255);
9
- --text: rgb(38, 48, 83);
10
- --text-muted: rgb(107, 113, 136);
11
- --text-subtle: rgb(117, 121, 129);
12
- --text-disabled: rgb(150, 152, 172);
13
- --text-decorative-light: rgb(168, 185, 212);
14
- --divider-subtle: rgba(30, 50, 100, 0.04);
15
- --divider: rgba(30, 50, 100, 0.07);
16
- --divider-strong: rgba(30, 50, 100, 0.09);
17
- --primary: rgb(103, 70, 255);
18
- --primary-light: rgb(147, 86, 255);
19
- --primary-pastel: rgba(234, 230, 255);
20
- --secondary: rgb(0, 151, 117);
21
- --secondary-light: rgb(0, 160, 129);
22
- --secondary-pastel: rgb(205, 238, 231);
23
- --secondary-bright: #0ab557;
24
- --input-background-light: rgb(243, 245, 249);
25
- --code-background: rgb(250, 250, 250);
26
- --code-background-dark: #435080;
27
- --selected-background: rgb(242, 245, 250);
28
- --breadcrumb-text: rgb(107, 113, 136);
29
- --breadcrumb-text-hover: rgb(117, 121, 129);
30
- --breadcrumb-icon: rgb(129, 131, 165);
31
- --canvas-background: rgb(249, 249, 249);
32
- --canvas-grid: rgba(0, 0, 0, 0.05);
33
- --sidebar-background: rgb(255, 255, 255);
34
- --sidebar-background-transparent: rgba(255, 255, 255, 0.85);
35
- --popover-background: rgb(252, 252, 252);
36
- --popover-divider: transparent;
37
- --listview-raised-background: rgba(0, 0, 0, 0.03);
38
- --listview-editing-background: #fff;
39
- --input-background: rgb(240, 242, 246);
40
- --list-view-hover-background: rgb(244, 246, 250);
41
- --list-view-thumbnail-background: var(--input-background);
42
- --slider-thumb-background: white;
43
- --slider-border: #9698ac;
44
- --mask: rgb(12, 193, 67);
45
- --transparent-checker: rgba(255, 255, 255, 0.8);
46
- --scrollbar: rgba(199, 199, 199, 0.8);
47
- --placeholder-dots: rgba(0, 0, 0, 0.3);
48
- --drag-outline: rgb(103, 70, 255);
49
- --active-background: rgba(0, 0, 0, 0.1);
50
- --thumbnail-background: #f0efff;
51
- --thumbnail-shadow: #d3ceed66;
52
- --inline-code-text: rgb(103, 70, 255);
53
- --inline-code-background: rgb(240, 242, 246);
54
- --text-link: rgb(103, 70, 255);
55
- --text-link-focused: rgb(147, 86, 255);
56
- --inset-top: 46px;
57
- --sidebar-width: 260px;
58
- --toolbar-height: 46px;
59
- --toolbar-separator: 8px;
60
- --inspector-h-separator: 8px;
61
- --inspector-v-separator: 10px;
62
- --dialog-padding: 16px;
63
- --input-height: 27px;
64
- --icon: rgb(129, 131, 165);
65
- --icon-selected: rgb(220, 220, 220);
66
- --warning: rgb(251, 211, 0);
67
- --segmented-control-item: rgb(139, 139, 139);
68
- --dot: rgba(0, 0, 0, 0.25);
69
- --row-highlight: #3390ff10;
70
- --table-row-background: var(--background);
71
- --interactable-z-index: 2;
72
- --label-z-index: 3;
73
- --menu-z-index: 5000;
74
- --chip-primary-bg: rgba(238, 229, 255, 0.2);
75
- --chip-secondary-bg: rgba(205, 238, 231, 0.2);
76
- --chip-error-bg: rgba(255, 219, 219, 0.2);
77
- --chip-default-bg: rgba(0, 0, 0, 0.1);
78
- --chip-primary-shadow: rgb(238, 229, 255);
79
- --chip-secondary-shadow: rgb(205, 238, 231);
80
- --chip-error-shadow: rgb(255, 219, 219);
81
- --chip-default-shadow: rgb(0, 0, 0);
82
- --floating-button: rgb(248, 248, 250);
83
- --block-border: rgb(184, 201, 218);
84
- --block-highlight: rgb(255, 165, 0);
6
+ --n-logo-fill: rgb(150, 152, 172);
7
+ --n-logo-highlight: rgb(150, 152, 172);
8
+ --n-background: rgb(255, 255, 255);
9
+ --n-text: rgb(38, 48, 83);
10
+ --n-text-muted: rgb(107, 113, 136);
11
+ --n-text-subtle: rgb(117, 121, 129);
12
+ --n-text-disabled: rgb(150, 152, 172);
13
+ --n-text-decorative-light: rgb(168, 185, 212);
14
+ --n-divider-subtle: rgba(30, 50, 100, 0.04);
15
+ --n-divider: rgba(30, 50, 100, 0.07);
16
+ --n-divider-strong: rgba(30, 50, 100, 0.09);
17
+ --n-primary: rgb(103, 70, 255);
18
+ --n-primary-light: rgb(147, 86, 255);
19
+ --n-primary-pastel: rgba(234, 230, 255);
20
+ --n-secondary: rgb(0, 151, 117);
21
+ --n-secondary-light: rgb(0, 160, 129);
22
+ --n-secondary-pastel: rgb(205, 238, 231);
23
+ --n-secondary-bright: #0ab557;
24
+ --n-input-background-light: rgb(243, 245, 249);
25
+ --n-code-background: rgb(250, 250, 250);
26
+ --n-code-background-dark: #435080;
27
+ --n-selected-background: rgb(242, 245, 250);
28
+ --n-breadcrumb-text: rgb(107, 113, 136);
29
+ --n-breadcrumb-text-hover: rgb(117, 121, 129);
30
+ --n-breadcrumb-icon: rgb(129, 131, 165);
31
+ --n-canvas-background: rgb(249, 249, 249);
32
+ --n-canvas-grid: rgba(0, 0, 0, 0.05);
33
+ --n-sidebar-background: rgb(255, 255, 255);
34
+ --n-sidebar-background-transparent: rgba(255, 255, 255, 0.85);
35
+ --n-popover-background: rgb(252, 252, 252);
36
+ --n-popover-divider: transparent;
37
+ --n-listview-raised-background: rgba(0, 0, 0, 0.03);
38
+ --n-listview-editing-background: #fff;
39
+ --n-input-background: rgb(240, 242, 246);
40
+ --n-list-view-hover-background: rgb(244, 246, 250);
41
+ --n-list-view-thumbnail-background: var(--n-input-background);
42
+ --n-slider-thumb-background: white;
43
+ --n-slider-border: #9698ac;
44
+ --n-mask: rgb(12, 193, 67);
45
+ --n-transparent-checker: rgba(255, 255, 255, 0.8);
46
+ --n-scrollbar: rgba(199, 199, 199, 0.8);
47
+ --n-placeholder-dots: rgba(0, 0, 0, 0.3);
48
+ --n-drag-outline: rgb(103, 70, 255);
49
+ --n-active-background: rgba(0, 0, 0, 0.1);
50
+ --n-thumbnail-background: #f0efff;
51
+ --n-thumbnail-shadow: #d3ceed66;
52
+ --n-inline-code-text: rgb(103, 70, 255);
53
+ --n-inline-code-background: rgb(240, 242, 246);
54
+ --n-text-link: rgb(103, 70, 255);
55
+ --n-text-link-focused: rgb(147, 86, 255);
56
+ --n-inset-top: 46px;
57
+ --n-sidebar-width: 260px;
58
+ --n-toolbar-height: 46px;
59
+ --n-toolbar-separator: 8px;
60
+ --n-inspector-h-separator: 8px;
61
+ --n-inspector-v-separator: 10px;
62
+ --n-dialog-padding: 16px;
63
+ --n-input-height: 27px;
64
+ --n-icon: rgb(129, 131, 165);
65
+ --n-icon-selected: rgb(220, 220, 220);
66
+ --n-warning: rgb(251, 211, 0);
67
+ --n-segmented-control-item: rgb(139, 139, 139);
68
+ --n-dot: rgba(0, 0, 0, 0.25);
69
+ --n-row-highlight: #3390ff10;
70
+ --n-table-row-background: var(--n-background);
71
+ --n-interactable-z-index: 2;
72
+ --n-label-z-index: 3;
73
+ --n-menu-z-index: 5000;
74
+ --n-chip-primary-bg: rgba(238, 229, 255, 0.2);
75
+ --n-chip-secondary-bg: rgba(205, 238, 231, 0.2);
76
+ --n-chip-error-bg: rgba(255, 219, 219, 0.2);
77
+ --n-chip-default-bg: rgba(0, 0, 0, 0.1);
78
+ --n-chip-primary-shadow: rgb(238, 229, 255);
79
+ --n-chip-secondary-shadow: rgb(205, 238, 231);
80
+ --n-chip-error-shadow: rgb(255, 219, 219);
81
+ --n-chip-default-shadow: rgb(0, 0, 0);
82
+ --n-floating-button: rgb(248, 248, 250);
83
+ --n-block-border: rgb(184, 201, 218);
84
+ --n-block-highlight: rgb(255, 165, 0);
85
+ --n-visual-editor-line-placeholder-content: "Write or press / for commands";
85
86
  }
86
87
 
87
88
  [data-theme="dark"] {
88
- --background: #111111;
89
- --logo-fill: rgb(248, 248, 250);
90
- --logo-highlight: rgb(248, 248, 250);
91
- --text: rgb(248, 248, 250);
92
- --text-muted: rgb(180, 179, 182);
93
- --text-subtle: rgb(180, 179, 182);
94
- --text-disabled: rgb(115, 114, 126);
95
- --divider-subtle: rgba(255, 255, 255, 0.04);
96
- --divider: rgba(255, 255, 255, 0.08);
97
- --divider-strong: rgba(0, 0, 0, 1);
98
- --primary: rgb(119, 66, 255);
99
- --primary-light: rgb(134, 86, 255);
100
- --secondary-bright: #36fe91;
101
- --input-background: rgba(181, 178, 255, 0.08);
102
- --input-background-light: rgba(181, 178, 255, 0.1);
103
- --code-background: rgb(20, 19, 23);
104
- --canvas-background: rgb(20, 19, 23);
105
- --canvas-grid: rgba(0, 0, 0, 0.1);
106
- --sidebar-background: rgb(34, 33, 39);
107
- --sidebar-background-transparent: rgba(34, 33, 39, 0.95);
108
- --popover-background: rgb(34, 33, 39);
109
- --popover-divider: rgba(255, 255, 255, 0.08);
110
- --listview-raised-background: rgba(181, 178, 255, 0.1);
111
- --listview-editing-background: #000;
112
- --list-view-hover-background: var(--input-background-light);
113
- --list-view-thumbnail-background: var(--input-background);
114
- --slider-thumb-background: var(--input-background-light);
115
- --slider-border: var(--divider);
116
- --mask: rgb(102, 187, 106);
117
- --transparent-checker: rgba(255, 255, 255, 0.3);
118
- --scrollbar: rgba(199, 199, 199, 0.2);
119
- --placeholder-dots: rgba(255, 255, 255, 0.3);
120
- --drag-outline: white;
121
- --active-background: rgba(181, 178, 255, 0.08);
122
- --thumbnail-background: #1f1d33;
123
- --thumbnail-shadow: #1f1d3366;
124
- --dot: rgba(255, 255, 255, 0.15);
125
- --table-row-background: var(--sidebar-background);
126
- --floating-button: #333333;
89
+ --n-background: #111111;
90
+ --n-logo-fill: rgb(248, 248, 250);
91
+ --n-logo-highlight: rgb(248, 248, 250);
92
+ --n-text: rgb(248, 248, 250);
93
+ --n-text-muted: rgb(180, 179, 182);
94
+ --n-text-subtle: rgb(180, 179, 182);
95
+ --n-text-disabled: rgb(115, 114, 126);
96
+ --n-divider-subtle: rgba(255, 255, 255, 0.04);
97
+ --n-divider: rgba(255, 255, 255, 0.08);
98
+ --n-divider-strong: rgba(0, 0, 0, 1);
99
+ --n-primary: rgb(119, 66, 255);
100
+ --n-primary-light: rgb(134, 86, 255);
101
+ --n-secondary-bright: #36fe91;
102
+ --n-input-background: rgba(181, 178, 255, 0.08);
103
+ --n-input-background-light: rgba(181, 178, 255, 0.1);
104
+ --n-code-background: rgb(20, 19, 23);
105
+ --n-canvas-background: rgb(20, 19, 23);
106
+ --n-canvas-grid: rgba(0, 0, 0, 0.1);
107
+ --n-sidebar-background: rgb(34, 33, 39);
108
+ --n-sidebar-background-transparent: rgba(34, 33, 39, 0.95);
109
+ --n-popover-background: rgb(34, 33, 39);
110
+ --n-popover-divider: rgba(255, 255, 255, 0.08);
111
+ --n-listview-raised-background: rgba(181, 178, 255, 0.1);
112
+ --n-listview-editing-background: #000;
113
+ --n-list-view-hover-background: var(--n-input-background-light);
114
+ --n-list-view-thumbnail-background: var(--n-input-background);
115
+ --n-slider-thumb-background: var(--n-input-background-light);
116
+ --n-slider-border: var(--n-divider);
117
+ --n-mask: rgb(102, 187, 106);
118
+ --n-transparent-checker: rgba(255, 255, 255, 0.3);
119
+ --n-scrollbar: rgba(199, 199, 199, 0.2);
120
+ --n-placeholder-dots: rgba(255, 255, 255, 0.3);
121
+ --n-drag-outline: white;
122
+ --n-active-background: rgba(181, 178, 255, 0.08);
123
+ --n-thumbnail-background: #1f1d33;
124
+ --n-thumbnail-shadow: #1f1d3366;
125
+ --n-dot: rgba(255, 255, 255, 0.15);
126
+ --n-table-row-background: var(--n-sidebar-background);
127
+ --n-floating-button: #333333;
128
+ }
129
+
130
+ .visual-editor-line-placeholder::after {
131
+ content: var(--n-visual-editor-line-placeholder-content);
132
+ color: var(--n-text-disabled);
133
+ pointer-events: none;
127
134
  }
package/src/index.tsx CHANGED
@@ -1,8 +1,10 @@
1
1
  // Components
2
2
  export * from "./components/ActionMenu";
3
3
  export * from "./components/ActivityIndicator";
4
+ export * from "./components/ai-assistant/AIAssistantLayout";
4
5
  export * from "./components/AnimatePresence";
5
6
  export * from "./components/Avatar";
7
+ export * from "./components/Banner";
6
8
  export * from "./components/Breadcrumbs";
7
9
  export * from "./components/Button";
8
10
  export * from "./components/Checkbox";
@@ -11,6 +13,7 @@ export * from "./components/Collection";
11
13
  export * from "./components/Combobox";
12
14
  export * from "./components/ComboboxMenu";
13
15
  export * from "./components/CommandPalette";
16
+ export * from "./components/connected-users-menu/ConnectedUsersMenuLayout";
14
17
  export * from "./components/ContextMenu";
15
18
  export * from "./components/Dialog";
16
19
  export * from "./components/Divider";
@@ -19,6 +22,7 @@ export * from "./components/Drawer";
19
22
  export * from "./components/DropdownMenu";
20
23
  export * from "./components/EditableText";
21
24
  export * from "./components/Fade";
25
+ export * from "./components/file-explorer/FileExplorerLayout";
22
26
  export * from "./components/FillInputField";
23
27
  export * from "./components/FillPreviewBackground";
24
28
  export * from "./components/FloatingWindow";
@@ -44,10 +48,12 @@ export * from "./components/ListView";
44
48
  export * from "./components/MediaThumbnail";
45
49
  export * from "./components/Message";
46
50
  export * from "./components/NoyaLogo";
51
+ export * from "./components/pipeline/PipelineResultLayout";
47
52
  export * from "./components/Popover";
48
53
  export * from "./components/Progress";
49
54
  export * from "./components/ScrollArea";
50
55
  export * from "./components/SearchCompletionMenu";
56
+ export * from "./components/Section";
51
57
  export * from "./components/SegmentedControl";
52
58
  export * from "./components/SelectMenu";
53
59
  export * from "./components/Slider";
@@ -85,6 +91,7 @@ export * from "./utils/getGradientBackground";
85
91
  export * from "./utils/colorFromString";
86
92
  export * from "./utils/combobox";
87
93
  export * from "./utils/fuzzyScorer";
94
+ export * from "./utils/moveTreeItem";
88
95
  export * from "./utils/selection";
89
96
  export * from "./utils/sketchColor";
90
97
  export * from "./utils/sketchPattern";
@@ -1,4 +1,4 @@
1
- import tailwindConfig from "../../tailwind.config";
1
+ import tailwindConfig from "@noya-app/noya-tailwind-config";
2
2
  import { convertKebabToCamelCase } from "./themeUtils";
3
3
 
4
4
  export type Theme = (typeof tailwindConfig.theme)["extend"];
@@ -1,18 +1,43 @@
1
- import tailwindConfig from "../../tailwind.config";
1
+ import tailwindConfig from "@noya-app/noya-tailwind-config";
2
2
 
3
3
  type ClassNameItem = string | number | BigInt | boolean | null | undefined;
4
- type Category = "text" | "flex";
4
+ type Category = "text" | "color" | "font" | "flex";
5
5
  type Options = {
6
6
  categories?: Category[];
7
7
  };
8
8
 
9
+ const colorKeys = Object.keys(tailwindConfig.theme.extend.colors).map(
10
+ (key) => `text-${key}`
11
+ );
12
+ const colorKeysSet = new Set(colorKeys);
9
13
  const textKeys = Object.keys(tailwindConfig.theme.extend.fontSize).map(
10
14
  (key) => `text-${key}`
11
15
  );
12
16
  const textKeysSet = new Set(textKeys);
17
+ const fontKeys = [
18
+ "thin",
19
+ "extralight",
20
+ "light",
21
+ "normal",
22
+ "medium",
23
+ "semibold",
24
+ "bold",
25
+ "extra-bold",
26
+ "black",
27
+ ].map((key) => `font-${key}`);
28
+ const fontKeysSet = new Set(fontKeys);
29
+ const flexKeysSet = new Set([
30
+ "flex-auto",
31
+ "flex-none",
32
+ "flex-[0_0_auto]",
33
+ "flex-1",
34
+ ]);
35
+
13
36
  const keyMap: Record<Category, Set<string>> = {
14
37
  text: textKeysSet,
15
- flex: new Set(["flex-auto", "flex-none", "flex-[0_0_auto]", "flex-1"]),
38
+ flex: flexKeysSet,
39
+ color: colorKeysSet,
40
+ font: fontKeysSet,
16
41
  };
17
42
 
18
43
  export function cx(...args: ClassNameItem[]): string {
@@ -168,12 +168,12 @@ export class ComboboxState<T extends string> {
168
168
 
169
169
  moveSelection(direction: "up" | "down") {
170
170
  const filteredItems = this.getFilteredItems();
171
- this.selectedIndex = getNextIndex(
172
- filteredItems,
173
- this.selectedIndex,
174
- direction === "down" ? "next" : "previous",
175
- (item) => isNonSelectableMenuItem(item)
176
- );
171
+ this.selectedIndex = getNextIndex({
172
+ items: filteredItems,
173
+ currentIndex: this.selectedIndex,
174
+ direction: direction === "down" ? "next" : "previous",
175
+ isDisabled: (item) => isNonSelectableMenuItem(item),
176
+ });
177
177
  this.notifyChange();
178
178
  }
179
179
 
@@ -257,7 +257,7 @@ export class ComboboxState<T extends string> {
257
257
  }
258
258
  }
259
259
 
260
- function filterWithGroupedSections<T extends string>(
260
+ export function filterWithGroupedSections<T extends string>(
261
261
  items: MenuItem<T>[],
262
262
  query: string
263
263
  ): ScoredMenuItem<T>[] {
@@ -341,12 +341,17 @@ function filterWithGroupedSections<T extends string>(
341
341
  return result;
342
342
  }
343
343
 
344
- export function getNextIndex<T>(
345
- items: T[],
346
- currentIndex: number,
347
- direction: "next" | "previous",
348
- isDisabled: (item: T) => boolean
349
- ): number {
344
+ export function getNextIndex<T>({
345
+ items,
346
+ currentIndex,
347
+ direction,
348
+ isDisabled,
349
+ }: {
350
+ items: T[];
351
+ currentIndex: number;
352
+ direction: "next" | "previous";
353
+ isDisabled: (item: T) => boolean;
354
+ }): number {
350
355
  // Make sure the current index is within bounds
351
356
  currentIndex =
352
357
  currentIndex < 0