@noya-app/noya-designsystem 0.1.64 → 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.
Files changed (115) hide show
  1. package/.turbo/turbo-build.log +13 -10
  2. package/CHANGELOG.md +12 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +501 -228
  5. package/dist/index.d.ts +501 -228
  6. package/dist/index.js +6738 -2571
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +6697 -2499
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +6 -6
  11. package/src/components/ActivityIndicator.tsx +9 -4
  12. package/src/components/ActivityLog.tsx +197 -0
  13. package/src/components/AnimatePresence.tsx +37 -22
  14. package/src/components/Avatar.tsx +42 -25
  15. package/src/components/Banner.tsx +57 -11
  16. package/src/components/BaseToolbar.tsx +29 -7
  17. package/src/components/Breadcrumbs.tsx +2 -2
  18. package/src/components/Button.tsx +23 -24
  19. package/src/components/Checkbox.tsx +6 -35
  20. package/src/components/Chip.tsx +45 -33
  21. package/src/components/Collection.tsx +16 -11
  22. package/src/components/ColorSwatch.tsx +3 -3
  23. package/src/components/ColorSwatchControl.tsx +2 -2
  24. package/src/components/Combobox.tsx +6 -6
  25. package/src/components/ComboboxMenu.tsx +6 -5
  26. package/src/components/CommandPalette.tsx +1 -1
  27. package/src/components/Dialog.tsx +6 -12
  28. package/src/components/Divider.tsx +8 -8
  29. package/src/components/DraggableMenuButton.tsx +9 -5
  30. package/src/components/Drawer.tsx +5 -5
  31. package/src/components/DropdownMenu.tsx +1 -1
  32. package/src/components/EditableText.tsx +2 -2
  33. package/src/components/Fade.tsx +13 -13
  34. package/src/components/FileUploadIndicator.tsx +11 -11
  35. package/src/components/FloatingWindow.tsx +2 -2
  36. package/src/components/Grid.tsx +18 -11
  37. package/src/components/GridView.tsx +32 -25
  38. package/src/components/IVirtualizedList.tsx +5 -0
  39. package/src/components/Icons.tsx +24 -4
  40. package/src/components/InputField.tsx +19 -19
  41. package/src/components/InspectorContainer.tsx +2 -2
  42. package/src/components/InspectorPrimitives.tsx +15 -9
  43. package/src/components/Label.tsx +4 -3
  44. package/src/components/LabeledElementView.tsx +3 -3
  45. package/src/components/LabeledField.tsx +6 -6
  46. package/src/components/List.tsx +103 -45
  47. package/src/components/ListMenu.tsx +91 -0
  48. package/src/components/ListNavigator.tsx +106 -0
  49. package/src/components/ListView.tsx +20 -1158
  50. package/src/components/MediaThumbnail.tsx +56 -15
  51. package/src/components/Message.tsx +5 -5
  52. package/src/components/Navigator.tsx +461 -0
  53. package/src/components/NoyaLogo.tsx +1 -1
  54. package/src/components/Popover.tsx +9 -5
  55. package/src/components/Progress.tsx +19 -9
  56. package/src/components/ResizableContainer.tsx +187 -0
  57. package/src/components/RingProgress.tsx +128 -0
  58. package/src/components/ScrollArea.tsx +4 -4
  59. package/src/components/ScrollableSidebar.tsx +10 -0
  60. package/src/components/SearchCompletionMenu.tsx +3 -3
  61. package/src/components/Section.tsx +107 -57
  62. package/src/components/SegmentedControl.tsx +29 -29
  63. package/src/components/SelectMenu.tsx +13 -20
  64. package/src/components/SelectionToolbar.tsx +4 -3
  65. package/src/components/Slider.tsx +9 -9
  66. package/src/components/Spacer.tsx +2 -2
  67. package/src/components/StackNavigator.tsx +378 -0
  68. package/src/components/Stepper.tsx +88 -0
  69. package/src/components/Switch.tsx +4 -4
  70. package/src/components/Tabs.tsx +3 -3
  71. package/src/components/Text.tsx +23 -13
  72. package/src/components/TextArea.tsx +3 -3
  73. package/src/components/Toast.tsx +4 -4
  74. package/src/components/Toolbar.tsx +50 -9
  75. package/src/components/ToolbarDrawer.tsx +2 -2
  76. package/src/components/Tooltip.tsx +1 -1
  77. package/src/components/TreeView.tsx +11 -4
  78. package/src/components/UserPointer.tsx +4 -4
  79. package/src/components/ai-assistant/AIAssistantLayout.tsx +8 -8
  80. package/src/components/blocks/ImageBlockComponent.tsx +13 -7
  81. package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +4 -4
  82. package/src/components/file-explorer/FileExplorerLayout.tsx +20 -8
  83. package/src/components/internal/Checkmark.tsx +1 -1
  84. package/src/components/internal/Menu.tsx +22 -18
  85. package/src/components/internal/MenuViewport.tsx +13 -6
  86. package/src/components/internal/SelectItem.tsx +3 -3
  87. package/src/components/internal/TextInput.tsx +5 -1
  88. package/src/components/listView/ListViewContexts.tsx +68 -0
  89. package/src/components/listView/ListViewEditableRowTitle.tsx +55 -0
  90. package/src/components/listView/ListViewRoot.tsx +521 -0
  91. package/src/components/listView/ListViewRow.tsx +475 -0
  92. package/src/components/listView/ListViewRowTitle.tsx +21 -0
  93. package/src/components/listView/types.ts +11 -0
  94. package/src/components/pipeline/PipelineResultLayout.tsx +6 -6
  95. package/src/components/sorting/DragRegistration.tsx +2 -1
  96. package/src/components/sorting/SharedDragProvider.tsx +91 -9
  97. package/src/components/sorting/Sortable.tsx +71 -17
  98. package/src/components/workspace/DrawerWorkspaceLayout.tsx +5 -5
  99. package/src/components/workspace/PanelWorkspaceLayout.tsx +65 -49
  100. package/src/components/workspace/VerticalTabMenu.tsx +25 -15
  101. package/src/components/workspace/WorkspaceLayout.tsx +30 -21
  102. package/src/contexts/DialogContext.tsx +17 -5
  103. package/src/hooks/useIndent.ts +3 -8
  104. package/src/index.css +24 -10
  105. package/src/index.tsx +10 -5
  106. package/src/utils/classNames.ts +52 -6
  107. package/src/utils/editableBlockStyles.ts +2 -2
  108. package/src/utils/formatByteSize.ts +1 -0
  109. package/src/utils/inputs.ts +8 -6
  110. package/src/utils/sketchColor.ts +0 -34
  111. package/tailwind.config.ts +1 -0
  112. package/src/components/FillInputField.tsx +0 -37
  113. package/src/components/FillPreviewBackground.tsx +0 -134
  114. package/src/components/GradientPicker.tsx +0 -90
  115. package/src/utils/getGradientBackground.tsx +0 -31
@@ -61,6 +61,8 @@ export type WorkspaceLayoutRef = {
61
61
  };
62
62
 
63
63
  export type SideOptions = {
64
+ // Whether to show the sidebar. Defaults to true.
65
+ visible?: boolean;
64
66
  style?: React.CSSProperties;
65
67
  className?: string;
66
68
  resizable?: boolean;
@@ -116,6 +118,7 @@ export const WorkspaceLayout = forwardRefGeneric(function WorkspaceLayout<
116
118
  sideTypeBreakpoint = 800,
117
119
  detectSize = "container",
118
120
  leftOptions: {
121
+ visible: leftVisible = true,
119
122
  minSize: leftMinSize = 200,
120
123
  maxSize: leftMaxSize = 500,
121
124
  initialSize: leftInitialSize = 280,
@@ -126,6 +129,7 @@ export const WorkspaceLayout = forwardRefGeneric(function WorkspaceLayout<
126
129
  showTabs: leftShowTabs = true,
127
130
  } = {},
128
131
  rightOptions: {
132
+ visible: rightVisible = true,
129
133
  minSize: rightMinSize = 200,
130
134
  maxSize: rightMaxSize = 500,
131
135
  initialSize: rightInitialSize = 280,
@@ -276,26 +280,28 @@ export const WorkspaceLayout = forwardRefGeneric(function WorkspaceLayout<
276
280
  (left ? leftSidebarPercentage : 0) -
277
281
  (right ? rightSidebarPercentage : 0);
278
282
 
279
- const leftPanel = left ? (
280
- <PanelInner
281
- style={leftStyle}
282
- className={cx("bg-sidebar-background flex-col", leftClassName)}
283
- >
284
- {leftTabValue ? renderPanelChildren(left, leftTabValue) : null}
285
- </PanelInner>
286
- ) : null;
287
-
288
- const rightPanel = right ? (
289
- <PanelInner
290
- style={rightStyle}
291
- className={cx("bg-sidebar-background flex-col", rightClassName)}
292
- >
293
- {rightTabValue ? renderPanelChildren(right, rightTabValue) : null}
294
- </PanelInner>
295
- ) : null;
283
+ const leftPanel =
284
+ left && leftVisible !== false ? (
285
+ <PanelInner
286
+ style={leftStyle}
287
+ className={cx("n-bg-sidebar-background n-flex-col", leftClassName)}
288
+ >
289
+ {leftTabValue ? renderPanelChildren(left, leftTabValue) : null}
290
+ </PanelInner>
291
+ ) : null;
292
+
293
+ const rightPanel =
294
+ right && rightVisible !== false ? (
295
+ <PanelInner
296
+ style={rightStyle}
297
+ className={cx("n-bg-sidebar-background n-flex-col", rightClassName)}
298
+ >
299
+ {rightTabValue ? renderPanelChildren(right, rightTabValue) : null}
300
+ </PanelInner>
301
+ ) : null;
296
302
 
297
303
  const centerPanel = (
298
- <PanelInner className="bg-canvas-background">{children}</PanelInner>
304
+ <PanelInner className="n-bg-canvas-background">{children}</PanelInner>
299
305
  );
300
306
 
301
307
  const leftSidebarOptions: PercentageSidebarOptions = useMemo(
@@ -359,12 +365,12 @@ export const WorkspaceLayout = forwardRefGeneric(function WorkspaceLayout<
359
365
  <div
360
366
  ref={containerRef}
361
367
  id={id}
362
- className={cx("flex flex-col bg-canvas-background relative", className)}
368
+ className={cx("n-flex n-flex-col n-bg-canvas-background n-relative", className)}
363
369
  style={style}
364
370
  data-theme={theme}
365
371
  >
366
372
  {toolbar}
367
- <div className="flex flex-row flex-1 relative">
373
+ <div className="n-flex n-flex-row n-flex-1 n-relative">
368
374
  {readyToRender && (
369
375
  <LayoutComponent
370
376
  leftPanel={leftPanel}
@@ -399,7 +405,10 @@ const PanelInner = memo(function PanelInner({
399
405
  className?: string;
400
406
  }) {
401
407
  return (
402
- <div style={style} className={cx("absolute inset-0 flex", className)}>
408
+ <div
409
+ style={style}
410
+ className={cx("n-absolute n-inset-0 n-min-w-0 n-flex", className)}
411
+ >
403
412
  {children}
404
413
  </div>
405
414
  );
@@ -28,12 +28,16 @@ function createDeferredPromise<T>() {
28
28
 
29
29
  type RenderableProps = { close: () => void };
30
30
 
31
+ type ClosablePromise<T> = Promise<T> & {
32
+ close: () => void;
33
+ };
34
+
31
35
  export type DialogContextValue = {
32
36
  openDialog(
33
37
  options: BaseDialogContents & {
34
38
  children: ReactNode | ((props: RenderableProps) => ReactNode);
35
39
  }
36
- ): Promise<void>;
40
+ ): ClosablePromise<void>;
37
41
 
38
42
  openInputDialog(
39
43
  options:
@@ -141,7 +145,11 @@ export const DialogProvider = function DialogProvider({
141
145
  },
142
146
  });
143
147
 
144
- return promise;
148
+ const closablePromise = Object.assign(promise, {
149
+ close: closeRef.current,
150
+ });
151
+
152
+ return closablePromise;
145
153
  }, []);
146
154
 
147
155
  const openConfirmation: DialogContextValue["openConfirmationDialog"] =
@@ -198,7 +206,11 @@ export const DialogProvider = function DialogProvider({
198
206
  },
199
207
  });
200
208
 
201
- return promise;
209
+ const closablePromise = Object.assign(promise, {
210
+ close: closeRef.current,
211
+ });
212
+
213
+ return closablePromise;
202
214
  },
203
215
  []
204
216
  );
@@ -271,7 +283,7 @@ export const DialogProvider = function DialogProvider({
271
283
  )}
272
284
  >
273
285
  {contents?.type === "confirmation" ? (
274
- <div className="flex flex-1 flex-row items-center">
286
+ <div className="n-flex n-flex-1 n-flex-row n-items-center">
275
287
  <Spacer.Horizontal />
276
288
  <Button
277
289
  onClick={() => {
@@ -316,7 +328,7 @@ export const DialogProvider = function DialogProvider({
316
328
  />
317
329
  </InputField.Root>
318
330
  <Spacer.Vertical size={20} />
319
- <div className="flex flex-1 flex-row items-center">
331
+ <div className="n-flex n-flex-1 n-flex-row n-items-center">
320
332
  <Spacer.Horizontal />
321
333
  <Button onClick={close}>Cancel</Button>
322
334
  <Spacer.Horizontal size={16} />
@@ -2,13 +2,8 @@
2
2
 
3
3
  import React from "react";
4
4
 
5
- export const IndentContext = React.createContext<{
6
- indentLevel: number;
7
- }>({
8
- indentLevel: 0,
9
- });
5
+ export const IndentContext = React.createContext<number>(0);
10
6
 
11
- export const useIndent = () => {
12
- const { indentLevel } = React.useContext(IndentContext);
13
- return indentLevel;
7
+ export const useIndent = (): number => {
8
+ return React.useContext(IndentContext);
14
9
  };
package/src/index.css CHANGED
@@ -1,3 +1,7 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
1
5
  :root {
2
6
  --n-primary-900: rgb(45, 25, 95); /* dark: --n-primary-pastel */
3
7
  --n-primary-800: rgb(64, 39, 140);
@@ -41,6 +45,7 @@
41
45
  --n-primary: var(--n-primary-600);
42
46
  --n-primary-light: var(--n-primary-400);
43
47
  --n-primary-pastel: var(--n-primary-100);
48
+ --n-primary-ring: color-mix(in srgb, var(--n-primary) 35%, transparent);
44
49
  --n-secondary: rgb(0, 151, 117);
45
50
  --n-secondary-light: rgb(0, 160, 129);
46
51
  --n-secondary-pastel: rgb(205, 238, 231);
@@ -86,6 +91,12 @@
86
91
  --n-active-background: var(--n-indigo-150);
87
92
  --n-thumbnail-background: #f0efff;
88
93
  --n-thumbnail-shadow: #d3ceed66;
94
+ --n-banner-info-background: var(--n-indigo-50);
95
+ --n-banner-info-border: var(--n-divider-strong);
96
+ --n-banner-info-text: #6579aa;
97
+ --n-banner-error-background: #ffe2e2;
98
+ --n-banner-error-border: var(--n-divider-strong);
99
+ --n-banner-error-text: #be1d1d;
89
100
  --n-inline-code-text: var(--n-primary-600);
90
101
  --n-inline-code-background: rgb(240, 242, 246);
91
102
  --n-text-link: var(--n-primary-600);
@@ -141,6 +152,14 @@
141
152
  --n-cm-error: #e45649;
142
153
  --n-cm-warning: #fb9d00;
143
154
  --n-cm-info: #3390ff;
155
+
156
+ .bg-sidebar-background {
157
+ --n-list-view-thumbnail-background: hsl(220 33% 97% / 1);
158
+ }
159
+
160
+ .bg-canvas-background {
161
+ --n-list-view-thumbnail-background: hsl(220 43% 95% / 1);
162
+ }
144
163
  }
145
164
 
146
165
  [data-theme="dark"] {
@@ -168,6 +187,7 @@
168
187
  --n-button-background-active-hover: var(--n-primary-600);
169
188
  --n-button-text: var(--n-text);
170
189
  --n-button-text-active: var(--n-primary-100);
190
+ --n-primary-ring: color-mix(in srgb, var(--n-primary) 45%, transparent);
171
191
  --n-secondary-bright: #36fe91;
172
192
  --n-code-background: rgb(20, 19, 23);
173
193
  --n-toolbar-drawer-background: color-mix(
@@ -224,14 +244,8 @@
224
244
  --n-cm-info: #3390ff;
225
245
  }
226
246
 
227
- .noya-styles {
228
- @tailwind base;
229
- @tailwind components;
230
- @tailwind utilities;
231
-
232
- .markdown-editor-line-placeholder::after {
233
- content: var(--n-markdown-editor-line-placeholder-content);
234
- color: var(--n-text-disabled);
235
- pointer-events: none;
236
- }
247
+ .markdown-editor-line-placeholder::after {
248
+ content: var(--n-markdown-editor-line-placeholder-content);
249
+ color: var(--n-text-disabled);
250
+ pointer-events: none;
237
251
  }
package/src/index.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  // Components
2
2
  export * from "./components/ActionMenu";
3
3
  export * from "./components/ActivityIndicator";
4
+ export * from "./components/ActivityLog";
4
5
  export * from "./components/ai-assistant/AIAssistantLayout";
5
6
  export * from "./components/AnimatePresence";
6
7
  export * from "./components/Avatar";
@@ -27,10 +28,7 @@ export * from "./components/EditableText";
27
28
  export * from "./components/Fade";
28
29
  export * from "./components/file-explorer/FileExplorerLayout";
29
30
  export * from "./components/FileUploadIndicator";
30
- export * from "./components/FillInputField";
31
- export * from "./components/FillPreviewBackground";
32
31
  export * from "./components/FloatingWindow";
33
- export * from "./components/GradientPicker";
34
32
  export * from "./components/Grid";
35
33
  export * from "./components/GridView";
36
34
  export * from "./components/IconButton";
@@ -44,17 +42,24 @@ export type {
44
42
  SelectableMenuItem,
45
43
  } from "./components/internal/Menu";
46
44
  export * from "./components/internal/MenuViewport";
45
+ export * from "./components/IVirtualizedList";
47
46
  export * from "./components/Label";
48
47
  export * from "./components/LabeledElementView";
49
48
  export * from "./components/LabeledField";
50
49
  export * from "./components/List";
50
+ export * from "./components/ListMenu";
51
+ export * from "./components/ListNavigator";
51
52
  export * from "./components/ListView";
52
53
  export * from "./components/MediaThumbnail";
53
54
  export * from "./components/Message";
55
+ export * from "./components/Navigator";
54
56
  export * from "./components/NoyaLogo";
55
57
  export * from "./components/pipeline/PipelineResultLayout";
56
58
  export * from "./components/Popover";
57
59
  export * from "./components/Progress";
60
+ export * from "./components/ResizableContainer";
61
+ export * from "./components/RingProgress";
62
+ export * from "./components/ScrollableSidebar";
58
63
  export * from "./components/ScrollArea";
59
64
  export * from "./components/SearchCompletionMenu";
60
65
  export * from "./components/Section";
@@ -67,6 +72,8 @@ export * from "./components/sorting/SharedDragProvider";
67
72
  export * from "./components/sorting/Sortable";
68
73
  export * from "./components/sorting/sorting";
69
74
  export * from "./components/Spacer";
75
+ export * from "./components/StackNavigator";
76
+ export * from "./components/Stepper";
70
77
  export * from "./components/Switch";
71
78
  export * from "./components/Tabs";
72
79
  export * from "./components/Text";
@@ -96,7 +103,6 @@ export * from "./theme";
96
103
  export * from "./utils/classNames";
97
104
  export * from "./utils/createSectionedMenu";
98
105
  export * from "./utils/formatByteSize";
99
- export * from "./utils/getGradientBackground";
100
106
  // Utils
101
107
  export * from "./utils/colorFromString";
102
108
  export * from "./utils/combobox";
@@ -104,7 +110,6 @@ export * from "./utils/editableBlockStyles";
104
110
  export * from "./utils/fuzzyScorer";
105
111
  export * from "./utils/moveTreeItem";
106
112
  export * from "./utils/selection";
107
- export * from "./utils/sketchColor";
108
113
  export * from "./utils/sketchPattern";
109
114
  export { default as withSeparatorElements } from "./utils/withSeparatorElements";
110
115
 
@@ -1,19 +1,42 @@
1
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" | "color" | "font" | "flex" | "position";
4
+ type Category =
5
+ | "text"
6
+ | "color"
7
+ | "font"
8
+ | "flex"
9
+ | "position"
10
+ | "textAlign"
11
+ | "rounded";
5
12
  type Options = {
6
13
  categories?: Category[];
7
14
  };
8
15
 
16
+ const TAILWIND_PREFIX = tailwindConfig.prefix ?? "";
17
+
18
+ function withTailwindPrefix(className: string): string {
19
+ return `${TAILWIND_PREFIX}${className}`;
20
+ }
21
+
22
+ function createPrefixedClassSet(classNames: string[]): Set<string> {
23
+ if (!TAILWIND_PREFIX) {
24
+ return new Set(classNames);
25
+ }
26
+
27
+ const prefixedClassNames = classNames.map(withTailwindPrefix);
28
+
29
+ return new Set([...classNames, ...prefixedClassNames]);
30
+ }
31
+
9
32
  const colorKeys = Object.keys(tailwindConfig.theme.extend.colors).map(
10
33
  (key) => `text-${key}`
11
34
  );
12
- const colorKeysSet = new Set(colorKeys);
35
+ const colorKeysSet = createPrefixedClassSet(colorKeys);
13
36
  const textKeys = Object.keys(tailwindConfig.theme.extend.fontSize).map(
14
37
  (key) => `text-${key}`
15
38
  );
16
- const textKeysSet = new Set(textKeys);
39
+ const textKeysSet = createPrefixedClassSet(textKeys);
17
40
  const fontKeys = [
18
41
  "thin",
19
42
  "extralight",
@@ -25,20 +48,43 @@ const fontKeys = [
25
48
  "extra-bold",
26
49
  "black",
27
50
  ].map((key) => `font-${key}`);
28
- const fontKeysSet = new Set(fontKeys);
29
- const flexKeysSet = new Set([
51
+ const fontKeysSet = createPrefixedClassSet(fontKeys);
52
+ const flexKeysSet = createPrefixedClassSet([
30
53
  "flex-auto",
31
54
  "flex-none",
32
55
  "flex-[0_0_auto]",
33
56
  "flex-1",
34
57
  ]);
35
- const positionKeysSet = new Set(["absolute", "relative", "fixed", "sticky"]);
58
+ const positionKeysSet = createPrefixedClassSet([
59
+ "absolute",
60
+ "relative",
61
+ "fixed",
62
+ "sticky",
63
+ ]);
64
+ const roundedKeysSet = createPrefixedClassSet([
65
+ "rounded",
66
+ "rounded-sm",
67
+ "rounded-md",
68
+ "rounded-lg",
69
+ "rounded-xl",
70
+ "rounded-2xl",
71
+ "rounded-3xl",
72
+ "rounded-full",
73
+ "rounded-none",
74
+ ]);
75
+ const textAlignKeysSet = createPrefixedClassSet([
76
+ "text-left",
77
+ "text-center",
78
+ "text-right",
79
+ ]);
36
80
  const keyMap: Record<Category, Set<string>> = {
37
81
  text: textKeysSet,
38
82
  flex: flexKeysSet,
39
83
  color: colorKeysSet,
40
84
  font: fontKeysSet,
41
85
  position: positionKeysSet,
86
+ textAlign: textAlignKeysSet,
87
+ rounded: roundedKeysSet,
42
88
  };
43
89
 
44
90
  export function cx(...args: ClassNameItem[]): string | undefined {
@@ -4,7 +4,7 @@ export const editableBlockStyles = (
4
4
  viewType: "editable" | "readOnly" | "preview" = "editable"
5
5
  ) =>
6
6
  cx(
7
- "relative outline-primary focus:outline focus:outline-1",
7
+ "n-relative n-outline-primary focus:n-outline focus:n-outline-1",
8
8
  viewType !== "preview" &&
9
- "hover:outline-2 [&:not(:has([data-editor-selectable-block]:hover))]:hover:outline"
9
+ "hover:n-outline-2 [&:not(:has([data-editor-selectable-block]:hover))]:hover:n-outline"
10
10
  );
@@ -1,6 +1,7 @@
1
1
  const byteSizeUnits = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
2
2
 
3
3
  export function formatByteSize(size: number) {
4
+ if (size === 0) return "0 B";
4
5
  const unitIndex = Math.floor(Math.log(size) / Math.log(1024));
5
6
  const unit = byteSizeUnits[unitIndex];
6
7
  const value = size / Math.pow(1024, unitIndex);
@@ -2,20 +2,22 @@ import { cx } from "./classNames";
2
2
 
3
3
  export type InputSize = "small" | "medium" | "large";
4
4
 
5
- const insetEndBaseStyles = "absolute inset-y-0 flex items-center z-label";
5
+ const insetEndBaseStyles =
6
+ "n-absolute n-inset-y-0 n-flex n-items-center n-z-label";
6
7
 
7
8
  export const getInsetEndStyles = (size: InputSize = "medium") => {
8
9
  return cx(
9
10
  insetEndBaseStyles,
10
11
  size === "large"
11
- ? "right-2"
12
+ ? "n-right-2"
12
13
  : size === "medium"
13
- ? "right-1.5"
14
+ ? "n-right-1.5"
14
15
  : size === "small"
15
- ? "right-0.5"
16
+ ? "n-right-0.5"
16
17
  : "",
17
- size === "small" ? "min-h-[19px]" : "min-h-input-height"
18
+ size === "small" ? "n-min-h-[19px]" : "n-min-h-input-height"
18
19
  );
19
20
  };
20
21
 
21
- export const startBaseStyles = "absolute left-1.5 inset-y-0 flex items-center";
22
+ export const startBaseStyles =
23
+ "n-absolute n-left-1.5 n-inset-y-0 n-flex n-items-center";
@@ -1,34 +0,0 @@
1
- import {
2
- hsvaToRgbaString,
3
- RgbaColor,
4
- rgbaToHex,
5
- rgbaToHsva,
6
- } from '@noya-app/noya-colorpicker';
7
- import type { Sketch } from '@noya-app/noya-file-format';
8
-
9
- export function sketchColorToRgba(value: Sketch.Color): RgbaColor {
10
- return {
11
- r: Math.floor(value.red * 255),
12
- g: Math.floor(value.green * 255),
13
- b: Math.floor(value.blue * 255),
14
- a: value.alpha,
15
- };
16
- }
17
-
18
- export function sketchColorToRgbaString(value: Sketch.Color): string {
19
- return hsvaToRgbaString(rgbaToHsva(sketchColorToRgba(value)));
20
- }
21
-
22
- export function rgbaToSketchColor(value: RgbaColor): Sketch.Color {
23
- return {
24
- _class: 'color',
25
- alpha: value.a,
26
- red: value.r / 255,
27
- green: value.g / 255,
28
- blue: value.b / 255,
29
- };
30
- }
31
-
32
- export function sketchColorToHex(value: Sketch.Color): string {
33
- return rgbaToHex(sketchColorToRgba(value)).toUpperCase();
34
- }
@@ -4,6 +4,7 @@ import type { Config } from "tailwindcss";
4
4
 
5
5
  const config = {
6
6
  ...noyaConfig,
7
+ prefix: "n-",
7
8
  plugins: [containerQueries],
8
9
  } satisfies Config;
9
10
 
@@ -1,37 +0,0 @@
1
- import { Sketch } from "@noya-app/noya-file-format";
2
- import React, { forwardRef, memo } from "react";
3
- import { cx } from "../utils/classNames";
4
- import { SketchPattern } from "../utils/sketchPattern";
5
- import { FillPreviewBackground } from "./FillPreviewBackground";
6
-
7
- const FillButton = forwardRef<
8
- HTMLButtonElement,
9
- React.ButtonHTMLAttributes<HTMLButtonElement>
10
- >(({ className, ...props }, ref) => (
11
- <button
12
- ref={ref}
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-active-input `,
15
- className
16
- )}
17
- {...props}
18
- />
19
- ));
20
-
21
- interface Props {
22
- id?: string;
23
- value?: Sketch.Color | Sketch.Gradient | SketchPattern;
24
- }
25
-
26
- export const FillInputField = memo(
27
- forwardRef<HTMLButtonElement, Props>(function FillInputField(
28
- { id, value, ...rest },
29
- ref
30
- ) {
31
- return (
32
- <FillButton ref={ref} id={id} {...rest}>
33
- <FillPreviewBackground value={value} />
34
- </FillButton>
35
- );
36
- })
37
- );
@@ -1,134 +0,0 @@
1
- "use client";
2
-
3
- import { Sketch } from "@noya-app/noya-file-format";
4
- // import { useSketchImage } from 'noya-renderer';
5
- import * as React from "react";
6
- import { useImageData } from "../contexts/ImageDataContext";
7
- import { useObjectURL } from "../hooks/useObjectURL";
8
- import { cssVars } from "../theme";
9
- import { getGradientBackground } from "../utils/getGradientBackground";
10
- import { sketchColorToRgbaString } from "../utils/sketchColor";
11
- import { SketchPattern } from "../utils/sketchPattern";
12
-
13
- const dotsHorizontalSvg = (fillColor: string) => `
14
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 15' fill='${fillColor}'>
15
- <path d='M3.625 7.5C3.625 8.12132 3.12132 8.625 2.5 8.625C1.87868 8.625 1.375 8.12132 1.375 7.5C1.375 6.87868 1.87868 6.375 2.5 6.375C3.12132 6.375 3.625 6.87868 3.625 7.5ZM8.625 7.5C8.625 8.12132 8.12132 8.625 7.5 8.625C6.87868 8.625 6.375 8.12132 6.375 7.5C6.375 6.87868 6.87868 6.375 7.5 6.375C8.12132 6.375 8.625 6.87868 8.625 7.5ZM12.5 8.625C13.1213 8.625 13.625 8.12132 13.625 7.5C13.625 6.87868 13.1213 6.375 12.5 6.375C11.8787 6.375 11.375 6.87868 11.375 7.5C11.375 8.12132 11.8787 8.625 12.5 8.625Z'></path>
16
- </svg>
17
- `;
18
-
19
- const Background = React.memo(function Background({
20
- background,
21
- }: {
22
- background?: string;
23
- }) {
24
- return (
25
- <span
26
- className={`${background ? `bg-[${background}]` : "bg-input-background"} absolute inset-0`}
27
- />
28
- );
29
- });
30
-
31
- function getPatternSizeAndPosition(
32
- fillType: Sketch.PatternFillType,
33
- tileScale: number
34
- ) {
35
- switch (fillType) {
36
- case Sketch.PatternFillType.Fit:
37
- return "center / contain";
38
- case Sketch.PatternFillType.Tile:
39
- return `top left / ${tileScale * 100}%`;
40
- case Sketch.PatternFillType.Fill:
41
- return "center / cover";
42
- case Sketch.PatternFillType.Stretch:
43
- return "center / 100% 100%";
44
- }
45
- }
46
-
47
- export const PatternPreviewBackground = React.memo(
48
- function PatternPreviewBackground({
49
- fillType,
50
- tileScale,
51
- imageRef,
52
- }: {
53
- fillType: Sketch.PatternFillType;
54
- tileScale: number;
55
- imageRef: string;
56
- }) {
57
- const image = useImageData(imageRef);
58
-
59
- const url = useObjectURL(image);
60
-
61
- const size = getPatternSizeAndPosition(fillType, tileScale);
62
-
63
- const background = React.useMemo(
64
- () =>
65
- [
66
- size,
67
- `url(${url})`,
68
- fillType === Sketch.PatternFillType.Tile ? "repeat" : "no-repeat",
69
- ].join(" "),
70
- [fillType, size, url]
71
- );
72
-
73
- return <Background background={background} />;
74
- }
75
- );
76
-
77
- const ColorPreviewBackground = React.memo(function ColorPreviewBackground({
78
- color,
79
- }: {
80
- color: Sketch.Color;
81
- }) {
82
- const background = React.useMemo(
83
- () => sketchColorToRgbaString(color),
84
- [color]
85
- );
86
-
87
- return <Background background={background} />;
88
- });
89
-
90
- const GradientPreviewBackground = React.memo(
91
- function GradientPreviewBackground({
92
- gradient,
93
- }: {
94
- gradient: Sketch.Gradient;
95
- }) {
96
- const background = React.useMemo(
97
- () => getGradientBackground(gradient.stops, gradient.gradientType, 180),
98
- [gradient.gradientType, gradient.stops]
99
- );
100
-
101
- return <Background background={background} />;
102
- }
103
- );
104
-
105
- interface Props {
106
- value?: Sketch.Color | Sketch.Gradient | SketchPattern;
107
- }
108
-
109
- const background = `center url("data:image/svg+xml;utf8,${dotsHorizontalSvg(
110
- cssVars.colors.placeholderDots
111
- )}") no-repeat`;
112
-
113
- export const FillPreviewBackground = React.memo(function FillPreviewBackground({
114
- value,
115
- }: Props) {
116
- if (!value) return <Background background={background} />;
117
-
118
- switch (value._class) {
119
- case "color":
120
- return <ColorPreviewBackground color={value} />;
121
- case "gradient":
122
- return <GradientPreviewBackground gradient={value} />;
123
- case "pattern":
124
- if (!value.image) return null;
125
-
126
- return (
127
- <PatternPreviewBackground
128
- fillType={value.patternFillType}
129
- tileScale={value.patternTileScale}
130
- imageRef={value.image._ref}
131
- />
132
- );
133
- }
134
- });