@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.
Files changed (143) hide show
  1. package/.turbo/turbo-build.log +13 -10
  2. package/CHANGELOG.md +25 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +648 -333
  5. package/dist/index.d.ts +648 -333
  6. package/dist/index.js +13813 -9157
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +13949 -9269
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +10 -22
  11. package/src/__tests__/validateDropIndicator.test.ts +26 -41
  12. package/src/__tests__/workspaceLayout.test.ts +281 -0
  13. package/src/components/ActionMenu.tsx +2 -0
  14. package/src/components/ActivityIndicator.tsx +13 -6
  15. package/src/components/ActivityLog.tsx +197 -0
  16. package/src/components/AnimatePresence.tsx +43 -26
  17. package/src/components/Avatar.tsx +45 -26
  18. package/src/components/Banner.tsx +57 -11
  19. package/src/components/BaseToolbar.tsx +67 -34
  20. package/src/components/Breadcrumbs.tsx +4 -2
  21. package/src/components/Button.tsx +28 -23
  22. package/src/components/Checkbox.tsx +6 -35
  23. package/src/components/Chip.tsx +47 -33
  24. package/src/components/Collection.tsx +20 -12
  25. package/src/components/ColorSwatch.tsx +42 -22
  26. package/src/components/ColorSwatchControl.tsx +7 -5
  27. package/src/components/Combobox.tsx +8 -6
  28. package/src/components/ComboboxMenu.tsx +6 -5
  29. package/src/components/CommandPalette.tsx +3 -1
  30. package/src/components/ContextMenu.tsx +3 -1
  31. package/src/components/Dialog.tsx +9 -13
  32. package/src/components/DimensionInput.tsx +2 -0
  33. package/src/components/Divider.tsx +18 -14
  34. package/src/components/DraggableMenuButton.tsx +11 -5
  35. package/src/components/Drawer.tsx +14 -6
  36. package/src/components/DropdownMenu.tsx +4 -2
  37. package/src/components/EditableText.tsx +4 -2
  38. package/src/components/Fade.tsx +13 -13
  39. package/src/components/FileUploadIndicator.tsx +108 -0
  40. package/src/components/FloatingWindow.tsx +4 -2
  41. package/src/components/Grid.tsx +58 -42
  42. package/src/components/GridView.tsx +65 -36
  43. package/src/components/IVirtualizedList.tsx +5 -0
  44. package/src/components/IconButton.tsx +2 -0
  45. package/src/components/Icons.tsx +24 -4
  46. package/src/components/InputField.tsx +21 -19
  47. package/src/components/InspectorContainer.tsx +2 -2
  48. package/src/components/InspectorPrimitives.tsx +15 -9
  49. package/src/components/Label.tsx +4 -3
  50. package/src/components/LabeledElementView.tsx +9 -5
  51. package/src/components/LabeledField.tsx +8 -6
  52. package/src/components/List.tsx +112 -46
  53. package/src/components/ListMenu.tsx +91 -0
  54. package/src/components/ListNavigator.tsx +106 -0
  55. package/src/components/ListView.tsx +22 -1147
  56. package/src/components/MediaThumbnail.tsx +84 -14
  57. package/src/components/Message.tsx +11 -12
  58. package/src/components/Navigator.tsx +461 -0
  59. package/src/components/NoyaLogo.tsx +1 -1
  60. package/src/components/Popover.tsx +12 -6
  61. package/src/components/Progress.tsx +31 -8
  62. package/src/components/ResizableContainer.tsx +187 -0
  63. package/src/components/RingProgress.tsx +128 -0
  64. package/src/components/ScrollArea.tsx +7 -5
  65. package/src/components/ScrollableSidebar.tsx +10 -0
  66. package/src/components/SearchCompletionMenu.tsx +5 -3
  67. package/src/components/Section.tsx +109 -57
  68. package/src/components/SegmentedControl.tsx +51 -25
  69. package/src/components/SelectMenu.tsx +16 -21
  70. package/src/components/SelectionToolbar.tsx +7 -4
  71. package/src/components/Slider.tsx +12 -10
  72. package/src/components/Spacer.tsx +2 -2
  73. package/src/components/StackNavigator.tsx +378 -0
  74. package/src/components/Stepper.tsx +88 -0
  75. package/src/components/Switch.tsx +7 -5
  76. package/src/components/Tabs.tsx +6 -4
  77. package/src/components/Text.tsx +29 -18
  78. package/src/components/TextArea.tsx +5 -3
  79. package/src/components/Toast.tsx +5 -5
  80. package/src/components/Toolbar.tsx +57 -10
  81. package/src/components/ToolbarDrawer.tsx +29 -0
  82. package/src/components/Tooltip.tsx +2 -2
  83. package/src/components/TreeView.tsx +13 -4
  84. package/src/components/UserPointer.tsx +6 -4
  85. package/src/components/ai-assistant/AIAssistantLayout.tsx +10 -8
  86. package/src/components/blocks/ImageBlockComponent.tsx +162 -0
  87. package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +6 -4
  88. package/src/components/file-explorer/FileExplorerLayout.tsx +22 -8
  89. package/src/components/internal/Checkmark.tsx +24 -0
  90. package/src/components/internal/Menu.tsx +24 -19
  91. package/src/components/internal/MenuViewport.tsx +15 -6
  92. package/src/components/internal/SelectItem.tsx +7 -26
  93. package/src/components/internal/TextInput.tsx +7 -1
  94. package/src/components/listView/ListViewContexts.tsx +68 -0
  95. package/src/components/listView/ListViewEditableRowTitle.tsx +55 -0
  96. package/src/components/listView/ListViewRoot.tsx +521 -0
  97. package/src/components/listView/ListViewRow.tsx +475 -0
  98. package/src/components/listView/ListViewRowTitle.tsx +21 -0
  99. package/src/components/listView/types.ts +11 -0
  100. package/src/components/pipeline/PipelineResultLayout.tsx +6 -6
  101. package/src/components/sorting/DragRegistration.tsx +10 -5
  102. package/src/components/sorting/SharedDragProvider.tsx +134 -27
  103. package/src/components/sorting/Sortable.tsx +90 -27
  104. package/src/components/sorting/createSharedDrag.tsx +7 -6
  105. package/src/components/sorting/sorting.ts +6 -9
  106. package/src/components/workspace/DrawerWorkspaceLayout.tsx +110 -29
  107. package/src/components/workspace/PanelWorkspaceLayout.tsx +148 -99
  108. package/src/components/workspace/VerticalTabMenu.tsx +46 -0
  109. package/src/components/workspace/WorkspaceLayout.tsx +76 -63
  110. package/src/components/workspace/constants.ts +4 -0
  111. package/src/components/workspace/panelStorage.ts +216 -0
  112. package/src/components/workspace/types.ts +11 -4
  113. package/src/contexts/DesignSystemConfiguration.tsx +12 -5
  114. package/src/contexts/DialogContext.tsx +19 -5
  115. package/src/contexts/FloatingWindowContext.tsx +2 -0
  116. package/src/contexts/GlobalInputBlurContext.tsx +2 -0
  117. package/src/contexts/ImageDataContext.tsx +2 -0
  118. package/src/contexts/LinkComponentContext.tsx +17 -0
  119. package/src/contexts/OpenPortalsContext.tsx +2 -0
  120. package/src/contexts/PortalScopeContext.tsx +2 -0
  121. package/src/hooks/mergeEventHandlers.ts +1 -1
  122. package/src/hooks/useHover.ts +30 -17
  123. package/src/hooks/useIndent.ts +5 -8
  124. package/src/hooks/useLabel.ts +2 -0
  125. package/src/hooks/useObjectURL.ts +5 -3
  126. package/src/hooks/usePlatform.ts +5 -3
  127. package/src/hooks/useTheme.ts +3 -1
  128. package/src/index.css +43 -10
  129. package/src/index.tsx +15 -7
  130. package/src/utils/classNames.ts +56 -9
  131. package/src/utils/combobox.ts +2 -0
  132. package/src/utils/editableBlockStyles.ts +2 -2
  133. package/src/utils/formatByteSize.ts +9 -0
  134. package/src/utils/inputs.ts +8 -6
  135. package/src/utils/sketchColor.ts +0 -34
  136. package/src/utils/withSeparatorElements.ts +1 -1
  137. package/tailwind.config.ts +1 -0
  138. package/src/components/FillInputField.tsx +0 -37
  139. package/src/components/FillPreviewBackground.tsx +0 -132
  140. package/src/components/GradientPicker.tsx +0 -88
  141. package/src/hooks/usePreservePanelSize.tsx +0 -183
  142. package/src/mediaQuery.ts +0 -13
  143. package/src/utils/getGradientBackground.tsx +0 -31
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // From: https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/src/useHover.ts
2
4
  // MIT License
3
5
 
@@ -8,13 +10,13 @@
8
10
  // @see https://github.com/adobe/react-spectrum/tree/452d1cb6a49f9f493757737edaf2b64014108de6/packages/%40react-aria
9
11
  // @see https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
10
12
 
11
- import * as React from 'react';
13
+ import * as React from "react";
12
14
 
13
15
  export interface HoverEvent {
14
16
  /** The type of hover event being fired. */
15
- type: 'hoverstart' | 'hoverend';
17
+ type: "hoverstart" | "hoverend";
16
18
  /** The pointer type that triggered the hover event. */
17
- pointerType: 'mouse' | 'pen';
19
+ pointerType: "mouse" | "pen";
18
20
  /** The target element of the hover event. */
19
21
  target: HTMLElement;
20
22
  }
@@ -58,17 +60,17 @@ function setGlobalIgnoreEmulatedMouseEvents() {
58
60
  }
59
61
 
60
62
  function handleGlobalPointerEvent(event: PointerEvent) {
61
- if (event.pointerType === 'touch') {
63
+ if (event.pointerType === "touch") {
62
64
  setGlobalIgnoreEmulatedMouseEvents();
63
65
  }
64
66
  }
65
67
 
66
68
  function setupGlobalTouchEvents() {
67
- if (typeof document === 'undefined') {
69
+ if (typeof document === "undefined") {
68
70
  return;
69
71
  }
70
72
 
71
- document.addEventListener('pointerup', handleGlobalPointerEvent);
73
+ document.addEventListener("pointerup", handleGlobalPointerEvent);
72
74
 
73
75
  hoverCount++;
74
76
  return function teardownGlobalTouchEvents() {
@@ -76,7 +78,7 @@ function setupGlobalTouchEvents() {
76
78
  if (hoverCount > 0) {
77
79
  return;
78
80
  }
79
- document.removeEventListener('pointerup', handleGlobalPointerEvent);
81
+ document.removeEventListener("pointerup", handleGlobalPointerEvent);
80
82
  };
81
83
  }
82
84
 
@@ -98,10 +100,14 @@ export function useHover(props: HoverProps = {}): HoverResult {
98
100
  const hoverProps = React.useMemo(
99
101
  function getHoverProps() {
100
102
  function triggerHoverStart(
101
- event: PointerEvent | React.PointerEvent | MouseEvent | React.MouseEvent,
102
- pointerType: 'mouse' | 'pen' | 'touch'
103
+ event:
104
+ | PointerEvent
105
+ | React.PointerEvent
106
+ | MouseEvent
107
+ | React.MouseEvent,
108
+ pointerType: "mouse" | "pen" | "touch"
103
109
  ) {
104
- if (isDisabled || pointerType === 'touch' || state.isHovered) {
110
+ if (isDisabled || pointerType === "touch" || state.isHovered) {
105
111
  return;
106
112
  }
107
113
 
@@ -110,7 +116,7 @@ export function useHover(props: HoverProps = {}): HoverResult {
110
116
 
111
117
  if (onHoverStart) {
112
118
  onHoverStart({
113
- type: 'hoverstart',
119
+ type: "hoverstart",
114
120
  target,
115
121
  pointerType,
116
122
  });
@@ -124,10 +130,14 @@ export function useHover(props: HoverProps = {}): HoverResult {
124
130
  }
125
131
 
126
132
  function triggerHoverEnd(
127
- event: PointerEvent | React.PointerEvent | MouseEvent | React.MouseEvent,
128
- pointerType: 'mouse' | 'pen' | 'touch'
133
+ event:
134
+ | PointerEvent
135
+ | React.PointerEvent
136
+ | MouseEvent
137
+ | React.MouseEvent,
138
+ pointerType: "mouse" | "pen" | "touch"
129
139
  ) {
130
- if (isDisabled || pointerType === 'touch' || !state.isHovered) {
140
+ if (isDisabled || pointerType === "touch" || !state.isHovered) {
131
141
  return;
132
142
  }
133
143
 
@@ -136,7 +146,7 @@ export function useHover(props: HoverProps = {}): HoverResult {
136
146
 
137
147
  if (onHoverEnd) {
138
148
  onHoverEnd({
139
- type: 'hoverend',
149
+ type: "hoverend",
140
150
  target,
141
151
  pointerType,
142
152
  });
@@ -151,7 +161,10 @@ export function useHover(props: HoverProps = {}): HoverResult {
151
161
 
152
162
  const hoverProps: React.HTMLAttributes<HTMLElement> = {
153
163
  onPointerEnter(event: React.PointerEvent<HTMLElement>) {
154
- if (globalIgnoreEmulatedMouseEvents && event.pointerType === 'mouse') {
164
+ if (
165
+ globalIgnoreEmulatedMouseEvents &&
166
+ event.pointerType === "mouse"
167
+ ) {
155
168
  return;
156
169
  }
157
170
  triggerHoverStart(event, event.pointerType);
@@ -170,4 +183,4 @@ export function useHover(props: HoverProps = {}): HoverResult {
170
183
  hoverProps,
171
184
  isHovered,
172
185
  };
173
- }
186
+ }
@@ -1,12 +1,9 @@
1
+ "use client";
2
+
1
3
  import React from "react";
2
4
 
3
- export const IndentContext = React.createContext<{
4
- indentLevel: number;
5
- }>({
6
- indentLevel: 0,
7
- });
5
+ export const IndentContext = React.createContext<number>(0);
8
6
 
9
- export const useIndent = () => {
10
- const { indentLevel } = React.useContext(IndentContext);
11
- return indentLevel;
7
+ export const useIndent = (): number => {
8
+ return React.useContext(IndentContext);
12
9
  };
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import React, { ReactNode } from "react";
2
4
 
3
5
  export type LabelType = "inset" | "start" | "end" | "above" | "none";
@@ -1,4 +1,6 @@
1
- import { useLayoutEffect, useMemo } from 'react';
1
+ "use client";
2
+
3
+ import { useLayoutEffect, useMemo } from "react";
2
4
 
3
5
  export function useObjectURL(object?: ArrayBuffer | Uint8Array | Blob) {
4
6
  const objectURL = useMemo(() => {
@@ -8,8 +10,8 @@ export function useObjectURL(object?: ArrayBuffer | Uint8Array | Blob) {
8
10
  object instanceof Uint8Array
9
11
  ? object
10
12
  : object !== undefined
11
- ? new Uint8Array(object)
12
- : new Uint8Array();
13
+ ? new Uint8Array(object)
14
+ : new Uint8Array();
13
15
 
14
16
  return URL.createObjectURL(new Blob([bytes]));
15
17
  }, [object]);
@@ -1,4 +1,6 @@
1
- import { useDesignSystemConfiguration } from '../contexts/DesignSystemConfiguration';
1
+ "use client";
2
+
3
+ import { useDesignSystemConfiguration } from "../contexts/DesignSystemConfiguration";
2
4
 
3
5
  export function usePlatform() {
4
6
  return useDesignSystemConfiguration().platform;
@@ -7,7 +9,7 @@ export function usePlatform() {
7
9
  /**
8
10
  * Either ctrl or meta, depending on the platform
9
11
  */
10
- export function usePlatformModKey(): 'ctrlKey' | 'metaKey' {
12
+ export function usePlatformModKey(): "ctrlKey" | "metaKey" {
11
13
  const platform = useDesignSystemConfiguration().platform;
12
- return platform === 'mac' ? 'metaKey' : 'ctrlKey';
14
+ return platform === "mac" ? "metaKey" : "ctrlKey";
13
15
  }
@@ -1,4 +1,6 @@
1
- import { useState, useEffect } from "react";
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
2
4
 
3
5
  /** @default light */
4
6
  export type UseThemeReturnType = "dark" | "light";
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);
@@ -11,6 +15,7 @@
11
15
  --n-primary-150: rgb(225, 219, 255);
12
16
  --n-primary-100: rgb(234, 230, 255); /* --n-primary-pastel */
13
17
  --n-primary-50: rgb(243, 242, 255);
18
+ --n-primary-25: rgb(250, 248, 255);
14
19
 
15
20
  --n-indigo-950: rgb(18, 26, 37);
16
21
  --n-indigo-900: rgb(30, 40, 60);
@@ -40,6 +45,7 @@
40
45
  --n-primary: var(--n-primary-600);
41
46
  --n-primary-light: var(--n-primary-400);
42
47
  --n-primary-pastel: var(--n-primary-100);
48
+ --n-primary-ring: color-mix(in srgb, var(--n-primary) 35%, transparent);
43
49
  --n-secondary: rgb(0, 151, 117);
44
50
  --n-secondary-light: rgb(0, 160, 129);
45
51
  --n-secondary-pastel: rgb(205, 238, 231);
@@ -58,6 +64,13 @@
58
64
  --n-button-background-active-hover: var(--n-primary-50);
59
65
  --n-button-text: var(--n-text);
60
66
  --n-button-text-active: var(--n-primary);
67
+ --n-toolbar-drawer-background: var(--n-primary-25);
68
+ --n-toolbar-drawer-border: color-mix(
69
+ in srgb,
70
+ var(--n-primary) 30%,
71
+ transparent
72
+ );
73
+ --n-toolbar-drawer-shadow: rgba(153, 153, 153, 0.25);
61
74
  --n-canvas-background: var(--n-indigo-25);
62
75
  --n-canvas-grid: rgba(0, 0, 0, 0.05);
63
76
  --n-sidebar-background: rgb(255, 255, 255);
@@ -78,6 +91,12 @@
78
91
  --n-active-background: var(--n-indigo-150);
79
92
  --n-thumbnail-background: #f0efff;
80
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;
81
100
  --n-inline-code-text: var(--n-primary-600);
82
101
  --n-inline-code-background: rgb(240, 242, 246);
83
102
  --n-text-link: var(--n-primary-600);
@@ -133,6 +152,14 @@
133
152
  --n-cm-error: #e45649;
134
153
  --n-cm-warning: #fb9d00;
135
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
+ }
136
163
  }
137
164
 
138
165
  [data-theme="dark"] {
@@ -160,8 +187,20 @@
160
187
  --n-button-background-active-hover: var(--n-primary-600);
161
188
  --n-button-text: var(--n-text);
162
189
  --n-button-text-active: var(--n-primary-100);
190
+ --n-primary-ring: color-mix(in srgb, var(--n-primary) 45%, transparent);
163
191
  --n-secondary-bright: #36fe91;
164
192
  --n-code-background: rgb(20, 19, 23);
193
+ --n-toolbar-drawer-background: color-mix(
194
+ in srgb,
195
+ var(--n-primary-900) 50%,
196
+ var(--n-background)
197
+ );
198
+ --n-toolbar-drawer-border: color-mix(
199
+ in srgb,
200
+ var(--n-primary-700) 30%,
201
+ transparent
202
+ );
203
+ --n-toolbar-drawer-shadow: rgba(255, 255, 255, 0.1);
165
204
  --n-canvas-background: rgb(20, 19, 23);
166
205
  --n-canvas-grid: rgba(0, 0, 0, 0.1);
167
206
  --n-sidebar-background: rgb(34, 33, 39);
@@ -205,14 +244,8 @@
205
244
  --n-cm-info: #3390ff;
206
245
  }
207
246
 
208
- .noya-styles {
209
- @tailwind base;
210
- @tailwind components;
211
- @tailwind utilities;
212
-
213
- .markdown-editor-line-placeholder::after {
214
- content: var(--n-markdown-editor-line-placeholder-content);
215
- color: var(--n-text-disabled);
216
- pointer-events: none;
217
- }
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;
218
251
  }
package/src/index.tsx CHANGED
@@ -1,10 +1,12 @@
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";
7
8
  export * from "./components/Banner";
9
+ export * from "./components/blocks/ImageBlockComponent";
8
10
  export * from "./components/Breadcrumbs";
9
11
  export * from "./components/Button";
10
12
  export * from "./components/Checkbox";
@@ -25,10 +27,8 @@ export * from "./components/DropdownMenu";
25
27
  export * from "./components/EditableText";
26
28
  export * from "./components/Fade";
27
29
  export * from "./components/file-explorer/FileExplorerLayout";
28
- export * from "./components/FillInputField";
29
- export * from "./components/FillPreviewBackground";
30
+ export * from "./components/FileUploadIndicator";
30
31
  export * from "./components/FloatingWindow";
31
- export * from "./components/GradientPicker";
32
32
  export * from "./components/Grid";
33
33
  export * from "./components/GridView";
34
34
  export * from "./components/IconButton";
@@ -42,17 +42,24 @@ export type {
42
42
  SelectableMenuItem,
43
43
  } from "./components/internal/Menu";
44
44
  export * from "./components/internal/MenuViewport";
45
+ export * from "./components/IVirtualizedList";
45
46
  export * from "./components/Label";
46
47
  export * from "./components/LabeledElementView";
47
48
  export * from "./components/LabeledField";
48
49
  export * from "./components/List";
50
+ export * from "./components/ListMenu";
51
+ export * from "./components/ListNavigator";
49
52
  export * from "./components/ListView";
50
53
  export * from "./components/MediaThumbnail";
51
54
  export * from "./components/Message";
55
+ export * from "./components/Navigator";
52
56
  export * from "./components/NoyaLogo";
53
57
  export * from "./components/pipeline/PipelineResultLayout";
54
58
  export * from "./components/Popover";
55
59
  export * from "./components/Progress";
60
+ export * from "./components/ResizableContainer";
61
+ export * from "./components/RingProgress";
62
+ export * from "./components/ScrollableSidebar";
56
63
  export * from "./components/ScrollArea";
57
64
  export * from "./components/SearchCompletionMenu";
58
65
  export * from "./components/Section";
@@ -65,6 +72,8 @@ export * from "./components/sorting/SharedDragProvider";
65
72
  export * from "./components/sorting/Sortable";
66
73
  export * from "./components/sorting/sorting";
67
74
  export * from "./components/Spacer";
75
+ export * from "./components/StackNavigator";
76
+ export * from "./components/Stepper";
68
77
  export * from "./components/Switch";
69
78
  export * from "./components/Tabs";
70
79
  export * from "./components/Text";
@@ -81,6 +90,7 @@ export * from "./contexts/DialogContext";
81
90
  export * from "./contexts/FloatingWindowContext";
82
91
  export * from "./contexts/GlobalInputBlurContext";
83
92
  export * from "./contexts/ImageDataContext";
93
+ export * from "./contexts/LinkComponentContext";
84
94
  export * from "./contexts/OpenPortalsContext";
85
95
  export * from "./contexts/PortalScopeContext";
86
96
  // Hooks
@@ -88,13 +98,11 @@ export * from "./hooks/useHover";
88
98
  export * from "./hooks/useIndent";
89
99
  export * from "./hooks/useLabel";
90
100
  export * from "./hooks/usePlatform";
91
- export * from "./hooks/usePreservePanelSize";
92
101
  export * from "./hooks/useTheme";
93
- export * from "./mediaQuery";
94
102
  export * from "./theme";
95
103
  export * from "./utils/classNames";
96
104
  export * from "./utils/createSectionedMenu";
97
- export * from "./utils/getGradientBackground";
105
+ export * from "./utils/formatByteSize";
98
106
  // Utils
99
107
  export * from "./utils/colorFromString";
100
108
  export * from "./utils/combobox";
@@ -102,7 +110,6 @@ export * from "./utils/editableBlockStyles";
102
110
  export * from "./utils/fuzzyScorer";
103
111
  export * from "./utils/moveTreeItem";
104
112
  export * from "./utils/selection";
105
- export * from "./utils/sketchColor";
106
113
  export * from "./utils/sketchPattern";
107
114
  export { default as withSeparatorElements } from "./utils/withSeparatorElements";
108
115
 
@@ -112,3 +119,4 @@ export * as InspectorPrimitives from "./components/InspectorPrimitives";
112
119
 
113
120
  export * from "./components/BaseToolbar";
114
121
  export * from "./components/Toolbar";
122
+ export * from "./components/ToolbarDrawer";
@@ -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,24 +48,48 @@ 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
- export function cx(...args: ClassNameItem[]): string {
45
- return args.filter(Boolean).join(" ").trim();
90
+ export function cx(...args: ClassNameItem[]): string | undefined {
91
+ const classes = args.filter(Boolean).join(" ").trim();
92
+ return classes.length > 0 ? classes : undefined;
46
93
  }
47
94
 
48
95
  const filterLastClassNameInCategory = ({
@@ -68,7 +115,7 @@ export function mergeConflictingClassNames(
68
115
  const classes = Array.isArray(classNames)
69
116
  ? cx(...classNames)
70
117
  : cx(classNames);
71
- let classNamesList = classes.split(/\s+/);
118
+ let classNamesList = classes?.split(/\s+/) ?? [];
72
119
  options?.categories?.forEach((category) => {
73
120
  classNamesList = filterLastClassNameInCategory({
74
121
  classNames: classNamesList,
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { chunkBy, partition } from "@noya-app/noya-utils";
2
4
  import { useSyncExternalStore } from "react";
3
5
  import {
@@ -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
  );
@@ -0,0 +1,9 @@
1
+ const byteSizeUnits = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
2
+
3
+ export function formatByteSize(size: number) {
4
+ if (size === 0) return "0 B";
5
+ const unitIndex = Math.floor(Math.log(size) / Math.log(1024));
6
+ const unit = byteSizeUnits[unitIndex];
7
+ const value = size / Math.pow(1024, unitIndex);
8
+ return `${value.toFixed(1)} ${unit}`;
9
+ }
@@ -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
- }
@@ -16,7 +16,7 @@ function flattenChildren(
16
16
  ): ReactNode[] {
17
17
  return Children.toArray(children).flatMap((child) => {
18
18
  if (traverseFragments && isValidElement(child) && child.type === Fragment) {
19
- return flattenChildren(child.props.children, traverseFragments);
19
+ return flattenChildren((child as any).props.children, traverseFragments);
20
20
  }
21
21
  return child;
22
22
  });
@@ -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
- );