@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
  import {
2
4
  forwardRefGeneric,
3
5
  memoGeneric,
@@ -70,6 +72,7 @@ export const Grid = memoGeneric(
70
72
  items,
71
73
  getId,
72
74
  getName,
75
+ getHref,
73
76
  // expandable,
74
77
  // getExpanded,
75
78
  getRenamable,
@@ -81,10 +84,11 @@ export const Grid = memoGeneric(
81
84
  renderThumbnail,
82
85
  renderAction,
83
86
  renderDetail,
87
+ renderRight,
84
88
  onSelectionChange,
85
89
  selectedIds = emptyArray,
86
90
  // itemRoleDescription = "clickable item",
87
- // detailPosition = "end",
91
+ detailPosition = "below",
88
92
  size = "medium",
89
93
  testHoveredId,
90
94
  testRenamingId,
@@ -156,10 +160,10 @@ export const Grid = memoGeneric(
156
160
  aria-multiselectable={true}
157
161
  minColumnWidth={minColumnWidth}
158
162
  scrollable={items.length > 0 && scrollable}
159
- contentClassName={cx(items.length === 0 && "flex flex-1")}
163
+ contentClassName={cx(items.length === 0 && "n-flex n-flex-1")}
160
164
  gap={gap}
161
165
  className={cx(
162
- isDropTargetActive && "bg-selected-list-item-background",
166
+ isDropTargetActive && "n-bg-selected-list-item-background",
163
167
  className
164
168
  )}
165
169
  {...dropTargetProps}
@@ -169,6 +173,7 @@ export const Grid = memoGeneric(
169
173
  <GridView.Section>
170
174
  {items.map((item) => {
171
175
  const id = getId(item);
176
+ const href = getHref?.(item);
172
177
  const isDropdownOpen = dropdownOpenId === id;
173
178
  const isHovered =
174
179
  testHoveredId === id ||
@@ -206,9 +211,20 @@ export const Grid = memoGeneric(
206
211
  />
207
212
  ));
208
213
 
214
+ const subtitle = (
215
+ <span
216
+ className={cx(isSelected && "n-text-selected-list-item-text")}
217
+ >
218
+ {renderDetail?.(item, isSelected)}
219
+ </span>
220
+ );
221
+
222
+ const right = renderRight?.(item, isSelected);
223
+
209
224
  return (
210
225
  <GridView.Item<M>
211
226
  key={id}
227
+ href={href}
212
228
  id={id}
213
229
  role="option"
214
230
  aria-selected={isSelected}
@@ -219,44 +235,44 @@ export const Grid = memoGeneric(
219
235
  setHoveredId(isHovering ? id : undefined);
220
236
  }}
221
237
  title={
222
- <EditableText
223
- tabIndex={isRenaming ? undefined : -1}
224
- value={getName(item)}
225
- focused={isRenaming}
226
- testFocused={isTestingRenaming}
227
- readOnly={!itemIsRenamable || !onRename}
228
- onSubmit={(value) => {
229
- onRename?.(item, value);
230
- setRenamingId(undefined);
231
- }}
232
- onBlur={() => {
233
- setRenamingId(undefined);
234
- }}
235
- // max height ensures preview text and input are one line
236
- textClassName="bg-listview-editing-background max-h-input-height"
237
- >
238
- {(props) => (
239
- <span
240
- {...props}
241
- className={cx(
242
- isSelected
243
- ? "text-selected-list-item-text"
244
- : "text-text",
245
- "truncate select-none"
246
- )}
247
- />
248
- )}
249
- </EditableText>
250
- }
251
- subtitle={
252
- <span
253
- className={cx(
254
- isSelected && "text-selected-list-item-text"
255
- )}
256
- >
257
- {renderDetail?.(item, isSelected)}
258
- </span>
238
+ <div className="n-flex n-items-center n-gap-2 n-flex-row">
239
+ <EditableText
240
+ className={cx(
241
+ (detailPosition === "end" || right) && "n-flex-1",
242
+ "n-truncate n-select-none"
243
+ )}
244
+ tabIndex={isRenaming ? undefined : -1}
245
+ value={getName(item)}
246
+ focused={isRenaming}
247
+ testFocused={isTestingRenaming}
248
+ readOnly={!itemIsRenamable || !onRename}
249
+ onSubmit={(value) => {
250
+ onRename?.(item, value);
251
+ setRenamingId(undefined);
252
+ }}
253
+ onBlur={() => {
254
+ setRenamingId(undefined);
255
+ }}
256
+ // max height ensures preview text and input are one line
257
+ textClassName="n-bg-listview-editing-background n-max-h-input-height"
258
+ >
259
+ {(props) => (
260
+ <span
261
+ {...props}
262
+ className={cx(
263
+ isSelected
264
+ ? "n-text-selected-list-item-text"
265
+ : "n-text-text",
266
+ "n-truncate n-select-none"
267
+ )}
268
+ />
269
+ )}
270
+ </EditableText>
271
+ {right && <div className="n-flex-none">{right}</div>}
272
+ {detailPosition === "end" && subtitle}
273
+ </div>
259
274
  }
275
+ subtitle={detailPosition === "below" && subtitle}
260
276
  loading={false}
261
277
  selected={isSelected}
262
278
  onClick={() => {
@@ -286,8 +302,8 @@ export const Grid = memoGeneric(
286
302
  {thumbnail && (
287
303
  <div
288
304
  className={cx(
289
- "rounded overflow-hidden flex-none flex w-full",
290
- isSelected && "text-selected-list-item-text"
305
+ "n-rounded n-overflow-hidden n-flex-none n-flex n-w-full",
306
+ isSelected && "n-text-selected-list-item-text"
291
307
  )}
292
308
  tabIndex={-1}
293
309
  >
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { KeyModifiers } from "@noya-app/noya-keymap";
2
4
  import { forwardRefGeneric, memoGeneric } from "@noya-app/react-utils";
3
5
  import React, {
@@ -11,6 +13,7 @@ import React, {
11
13
  useContext,
12
14
  useMemo,
13
15
  } from "react";
16
+ import { useLinkComponent } from "../contexts/LinkComponentContext";
14
17
  import { useHover } from "../hooks/useHover";
15
18
  import { cx, mergeConflictingClassNames } from "../utils/classNames";
16
19
  import withSeparatorElements from "../utils/withSeparatorElements";
@@ -31,9 +34,9 @@ const ItemTitle = ({
31
34
  return (
32
35
  <span
33
36
  className={cx(
34
- "font-sans text-heading5 text-text-muted font-medium",
37
+ "n-font-sans n-text-heading5 n-text-text-muted n-font-medium",
35
38
  showBackground &&
36
- "bg-sidebar-background border border-divider-subtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
39
+ "n-bg-sidebar-background n-n-border n-border-divider-subtle n-rounded-[2px] n-backdrop-blur-[4px] n-p-[2px_4px]"
37
40
  )}
38
41
  >
39
42
  {children}
@@ -51,9 +54,9 @@ const ItemDescription = ({
51
54
  return (
52
55
  <span
53
56
  className={cx(
54
- "font-sans text-sm text-text-muted select-none truncate",
57
+ "n-font-sans n-text-sm n-text-text-muted n-select-none n-truncate",
55
58
  showBackground &&
56
- "bg-sidebar-background border border-divider-subtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
59
+ "n-bg-sidebar-background n-n-border n-border-divider-subtle n-rounded-[2px] n-backdrop-blur-[4px] n-p-[2px_4px]"
57
60
  )}
58
61
  >
59
62
  {children}
@@ -70,7 +73,10 @@ const SectionTitle = ({
70
73
  }) => {
71
74
  return (
72
75
  <span
73
- className={`font-sans text-heading3 font-medium user-select-none truncate ${last ? "text-text" : "text-text-muted"}`}
76
+ className={cx(
77
+ "n-font-sans n-text-heading3 n-font-medium n-user-select-none n-truncate",
78
+ last ? "n-text-text" : "n-text-text-muted"
79
+ )}
74
80
  >
75
81
  {children}
76
82
  </span>
@@ -79,12 +85,13 @@ const SectionTitle = ({
79
85
 
80
86
  interface ItemProps<MenuItemType extends string = string> {
81
87
  id: string;
88
+ href?: string;
82
89
  title?: ReactNode;
83
90
  subtitle?: ReactNode;
84
91
  loading?: boolean;
85
92
  selected?: boolean;
86
93
  onClick?: (event: React.MouseEvent) => void;
87
- onSelect?: (options: KeyModifiers) => void;
94
+ onSelect?: (options: KeyModifiers & { stopPropagation(): void }) => void;
88
95
  onDoubleClick?: () => void;
89
96
  onHoverChange?: (isHovering: boolean) => void;
90
97
  children?: ReactNode;
@@ -105,6 +112,7 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
105
112
  >(
106
113
  {
107
114
  id,
115
+ href,
108
116
  title,
109
117
  subtitle,
110
118
  loading,
@@ -125,23 +133,27 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
125
133
  testShowInsideDropIndicator: showInsideDropIndicator = false,
126
134
  ...props
127
135
  }: ItemProps<MenuItemType>,
128
- forwardedRef: ForwardedRef<HTMLDivElement>
136
+ forwardedRef: ForwardedRef<HTMLElement>
129
137
  ) {
130
138
  const { hoverProps } = useHover({
131
139
  onHoverChange,
132
140
  });
133
141
 
134
- const { textPosition, bordered, disabled } = useContext(GridViewContext);
142
+ const { textPosition, bordered, disabled, alwaysShowSubtitles } =
143
+ useContext(GridViewContext);
135
144
 
136
145
  const handleClick = useCallback(
137
146
  (event: React.MouseEvent) => {
138
147
  event.stopPropagation();
139
- event.preventDefault();
148
+
149
+ if (!href) {
150
+ event.preventDefault();
151
+ }
140
152
 
141
153
  onClick?.(event);
142
154
  onSelect?.(event);
143
155
  },
144
- [onClick, onSelect]
156
+ [href, onClick, onSelect]
145
157
  );
146
158
 
147
159
  const handleKeyDown = useCallback(
@@ -159,21 +171,25 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
159
171
  [onSelect, onKeyDown]
160
172
  );
161
173
 
174
+ const LinkComponent = useLinkComponent();
175
+ const Component = typeof href === "string" ? LinkComponent : "div";
176
+
162
177
  let element = (
163
- <div
178
+ <Component
164
179
  {...props}
165
180
  className={cx(
166
- "flex flex-col relative rounded p-2 -m-2 text-text",
167
- "cursor-pointer",
168
- "active:opacity-70",
169
- selected && "bg-selected-list-item-background",
170
- hovered && "bg-list-view-hover-background",
171
- disabled && "opacity-50",
172
- showInsideDropIndicator && "ring-2 ring-primary ring-inset",
173
- "focus:ring-2 focus:ring-primary focus:ring-inset focus:outline-none"
181
+ "n-flex n-flex-col n-relative n-rounded n-p-2 -n-m-2 n-text-text",
182
+ "n-cursor-pointer",
183
+ "active:n-opacity-70",
184
+ selected && "n-bg-selected-list-item-background",
185
+ hovered && "n-bg-list-view-hover-background",
186
+ disabled && "n-opacity-50",
187
+ showInsideDropIndicator && "n-ring-2 n-ring-primary n-ring-inset",
188
+ "focus:n-ring-2 focus:n-ring-primary focus:n-ring-inset focus:n-outline-none"
174
189
  )}
175
190
  id={id}
176
- ref={forwardedRef}
191
+ href={href}
192
+ ref={forwardedRef as ForwardedRef<HTMLAnchorElement & HTMLDivElement>}
177
193
  {...hoverProps}
178
194
  tabIndex={disabled ? undefined : 0}
179
195
  onKeyDown={handleKeyDown}
@@ -183,8 +199,10 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
183
199
  >
184
200
  <div
185
201
  className={cx(
186
- "flex items-center justify-center rounded",
187
- bordered ? "border border-divider" : "border border-transparent"
202
+ "n-flex n-items-center n-justify-center n-rounded",
203
+ bordered
204
+ ? "n-border n-border-divider"
205
+ : "n-border n-border-transparent"
188
206
  )}
189
207
  style={style}
190
208
  >
@@ -194,12 +212,16 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
194
212
  <>
195
213
  <Spacer.Vertical size={8} />
196
214
  <ItemTitle>{title || " "}</ItemTitle>
197
- <Spacer.Vertical size={2} />
198
- <ItemDescription>{subtitle || " "}</ItemDescription>
215
+ {(alwaysShowSubtitles || subtitle) && (
216
+ <>
217
+ <Spacer.Vertical size={2} />
218
+ <ItemDescription>{subtitle || " "}</ItemDescription>
219
+ </>
220
+ )}
199
221
  </>
200
222
  )}
201
223
  {textPosition === "overlay" && hovered && (title || subtitle) && (
202
- <div className="absolute inset-0 flex flex-col justify-end items-start p-1 pointer-events-none truncate gap-0.5">
224
+ <div className="n-absolute n-inset-0 n-flex n-flex-col n-justify-end n-items-start n-p-1 n-pointer-events-none n-truncate n-gap-0.5">
203
225
  {title && <ItemTitle showBackground>{title}</ItemTitle>}
204
226
  {subtitle && (
205
227
  <ItemDescription showBackground>{subtitle}</ItemDescription>
@@ -207,16 +229,16 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
207
229
  </div>
208
230
  )}
209
231
  {action && (
210
- <div className="absolute top-[7px] right-[7px] flex flex-col justify-end items-start p-1 truncate gap-0.5">
232
+ <div className="n-absolute n-top-[7px] n-right-[7px] n-flex n-flex-col n-justify-end n-items-start n-p-1 n-truncate n-gap-0.5">
211
233
  {action}
212
234
  </div>
213
235
  )}
214
236
  {loading && (
215
- <div className="flex flex-col justify-start items-end p-1 pointer-events-none animate-shimmer absolute inset-0 bg-gradient-to-r from-white/0 via-[rgb(226,232,240)]/50 to-white/0 bg-length:200%_100%]">
237
+ <div className="n-flex n-flex-col n-justify-start n-items-end n-p-1 n-pointer-events-none n-animate-shimmer n-absolute n-inset-0 n-bg-gradient-to-r n-from-white/0 n-via-[rgb(226,232,240)]/50 n-to-white/0 n-bg-[length:200%_100%]">
216
238
  <ActivityIndicator opacity={0.5} size={13} />
217
239
  </div>
218
240
  )}
219
- </div>
241
+ </Component>
220
242
  );
221
243
 
222
244
  if (menuItems && onSelectMenuItem) {
@@ -235,7 +257,7 @@ const GridViewItem = forwardRefGeneric(function GridViewItem<
235
257
  element = (
236
258
  <Tooltip
237
259
  content={
238
- <div className="flex flex-col gap-0.5">
260
+ <div className="n-flex n-flex-col gap-0.5">
239
261
  <ItemTitle>{title}</ItemTitle>
240
262
  <ItemDescription>{subtitle}</ItemDescription>
241
263
  </div>
@@ -255,6 +277,7 @@ type GridViewContextValue = {
255
277
  bordered: boolean;
256
278
  disabled: boolean;
257
279
  gap: number;
280
+ alwaysShowSubtitles: boolean;
258
281
  };
259
282
 
260
283
  const GridViewContext = createContext<GridViewContextValue>({
@@ -263,6 +286,7 @@ const GridViewContext = createContext<GridViewContextValue>({
263
286
  bordered: false,
264
287
  disabled: false,
265
288
  gap: 0,
289
+ alwaysShowSubtitles: false,
266
290
  });
267
291
 
268
292
  interface GridViewRootProps extends Partial<GridViewContextValue> {
@@ -277,6 +301,7 @@ interface GridViewRootProps extends Partial<GridViewContextValue> {
277
301
  role?: string;
278
302
  renderEmptyState?: () => ReactNode;
279
303
  contentClassName?: string;
304
+ alwaysShowSubtitles?: boolean;
280
305
  }
281
306
 
282
307
  const GridViewRoot = forwardRef(function GridViewRoot(
@@ -291,6 +316,7 @@ const GridViewRoot = forwardRef(function GridViewRoot(
291
316
  disabled = false,
292
317
  className,
293
318
  contentClassName,
319
+ alwaysShowSubtitles = false,
294
320
  ...props
295
321
  }: GridViewRootProps,
296
322
  forwardedRef: ForwardedRef<HTMLDivElement>
@@ -306,20 +332,21 @@ const GridViewRoot = forwardRef(function GridViewRoot(
306
332
  );
307
333
 
308
334
  const contextValue = useMemo(
309
- () => ({
335
+ (): GridViewContextValue => ({
310
336
  minColumnWidth,
311
337
  textPosition,
312
338
  bordered,
313
339
  disabled,
314
340
  gap,
341
+ alwaysShowSubtitles,
315
342
  }),
316
- [bordered, disabled, gap, minColumnWidth, textPosition]
343
+ [bordered, disabled, gap, minColumnWidth, textPosition, alwaysShowSubtitles]
317
344
  );
318
345
 
319
346
  const mergedClassName = useMemo(() => {
320
347
  const baseClassName = cx(
321
- "flex flex-col -mx-3",
322
- scrollable ? "basis-0 min-h-0" : "flex-none",
348
+ "n-flex n-flex-col n--mx-3",
349
+ scrollable ? "n-basis-0 n-min-h-0" : "n-flex-none",
323
350
  className
324
351
  );
325
352
 
@@ -328,7 +355,9 @@ const GridViewRoot = forwardRef(function GridViewRoot(
328
355
  });
329
356
  }, [className, scrollable]);
330
357
 
331
- const content = <div className={cx("p-3", contentClassName)}>{children}</div>;
358
+ const content = (
359
+ <div className={cx("n-p-3", contentClassName)}>{children}</div>
360
+ );
332
361
 
333
362
  return (
334
363
  <GridViewContext.Provider value={contextValue}>
@@ -367,7 +396,7 @@ function GridViewSection({
367
396
  ) : (
368
397
  <div
369
398
  role="presentation"
370
- className={cx("grid text-text", className)}
399
+ className={cx("n-grid n-text-text", className)}
371
400
  style={styles}
372
401
  >
373
402
  {children}
@@ -379,7 +408,7 @@ function GridViewSectionHeader({ title }: { title: string }) {
379
408
  const grouped = title.split("/");
380
409
 
381
410
  return (
382
- <div className="px-5">
411
+ <div className="n-px-5">
383
412
  <Spacer.Vertical size={24} />
384
413
  {withSeparatorElements(
385
414
  grouped.map((title, index) => (
@@ -0,0 +1,5 @@
1
+ "use client";
2
+
3
+ export interface IVirtualizedList {
4
+ scrollToIndex(index: number): void;
5
+ }
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import * as React from "react";
2
4
  import { cssVars } from "../theme";
3
5
  import { Button, ButtonProps } from "./Button";
@@ -1,18 +1,38 @@
1
1
  import * as Icons from "@noya-app/noya-icons";
2
+ import { IconProps } from "@noya-app/noya-icons";
2
3
  import * as React from "react";
3
4
 
4
5
  export type IconName = keyof typeof Icons;
5
6
 
6
7
  export { Icons };
7
8
 
8
- export function renderIcon(
9
- iconName: Exclude<React.ReactNode, string> | IconName
10
- ): React.ReactNode {
9
+ export type IconProp = Exclude<React.ReactNode, string> | IconName;
10
+
11
+ export function renderIcon(iconName: IconProp): React.ReactNode {
11
12
  if (typeof iconName === "string") {
12
13
  const Icon = Icons[iconName as IconName];
13
14
 
14
- return <Icon />;
15
+ return <Icon className="n-min-h-[15px]" />;
15
16
  }
16
17
 
17
18
  return iconName;
18
19
  }
20
+
21
+ const didWarn = new Set<string>();
22
+
23
+ export function Icon({
24
+ name,
25
+ ...props
26
+ }: { name: IconName } & Omit<IconProps, "name">) {
27
+ const Icon = Icons[name];
28
+
29
+ if (!Icon) {
30
+ if (!didWarn.has(name)) {
31
+ console.warn(`Icon ${name} not found in @noya-app/noya-icons`);
32
+ didWarn.add(name);
33
+ }
34
+ return null;
35
+ }
36
+
37
+ return <Icon {...props} />;
38
+ }
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { DropdownChevronIcon } from "@noya-app/noya-icons";
2
4
  import { memoGeneric, useMergeRefs, useSize } from "@noya-app/react-utils";
3
5
  import { Property } from "csstype";
@@ -162,7 +164,7 @@ const InputFieldButton = memo(
162
164
  size={size === "medium" ? "normal" : size}
163
165
  className={cx(
164
166
  className,
165
- variant === "floating" && "bg-transparent shadow-none"
167
+ variant === "floating" && "n-bg-transparent n-shadow-none"
166
168
  )}
167
169
  {...rest}
168
170
  >
@@ -226,21 +228,21 @@ const InputElement = forwardRef(
226
228
  });
227
229
 
228
230
  const inputClassName = cx(
229
- "flex w-0 flex-1 relative border-0 outline-none min-w-0 self-stretch rounded bg-input-background focus:ring-2 focus:ring-primary placeholder:text-text-disabled transition-all",
231
+ "n-flex n-w-0 n-flex-1 n-relative n-border-0 n-outline-none n-min-w-0 n-self-stretch n-rounded n-bg-input-background focus:n-ring-2 focus:n-ring-primary placeholder:n-text-text-disabled n-transition-[box-shadow]",
230
232
  readOnly
231
- ? "text-text-muted"
233
+ ? "n-text-text-muted"
232
234
  : disabled
233
- ? "text-text-disabled"
234
- : "text-text",
235
- "font-sans font-normal",
236
- $textAlign && `text-${$textAlign}`,
235
+ ? "n-text-text-disabled"
236
+ : "n-text-text",
237
+ "n-font-sans n-font-normal",
238
+ $textAlign && `n-text-${$textAlign}`,
237
239
  size === "small"
238
- ? "text-[11px] leading-[19px] py-[1px]"
240
+ ? "n-text-[11px] n-leading-[19px] n-py-[1px]"
239
241
  : size === "large"
240
- ? "py-2.5 text-heading5"
242
+ ? "n-py-2.5 n-text-heading5"
241
243
  : size === "medium"
242
- ? "py-1 text-heading5"
243
- : $variant === "bare" && "py-1 -m-1",
244
+ ? "n-py-1 n-text-heading5"
245
+ : $variant === "bare" && "n-py-1 -n-m-1",
244
246
  className
245
247
  );
246
248
 
@@ -475,7 +477,7 @@ const RootContainer = forwardRef<
475
477
  >(({ $width, className, ...props }, ref) => (
476
478
  <div
477
479
  ref={ref}
478
- className={cx("flex flex-row relative flex-1", className)}
480
+ className={cx("n-flex n-flex-row n-relative n-flex-1", className)}
479
481
  style={{
480
482
  maxWidth: $width || $width === 0 ? `${$width}px` : undefined,
481
483
  ...props.style,
@@ -570,7 +572,7 @@ function InputFieldRoot({
570
572
 
571
573
  const insetLabel = useMemo(
572
574
  () => (
573
- <Label htmlFor={id} className="!text-text-disabled">
575
+ <Label htmlFor={id} className="!n-text-text-disabled">
574
576
  {labelProp ?? label}
575
577
  </Label>
576
578
  ),
@@ -588,7 +590,7 @@ function InputFieldRoot({
588
590
  {(end || label) && (
589
591
  <span
590
592
  ref={endRef}
591
- className={cx(endStyles, label && end && "gap-1.5", endClassName)}
593
+ className={cx(endStyles, label && end && "n-gap-1.5", endClassName)}
592
594
  >
593
595
  {labelProp
594
596
  ? insetLabel
@@ -624,7 +626,7 @@ function InputFieldRoot({
624
626
  >
625
627
  {measuredWidthObject && (
626
628
  <div
627
- className="flex flex-col overflow-hidden"
629
+ className="n-flex n-flex-col n-overflow-hidden"
628
630
  style={measuredWidthObject}
629
631
  >
630
632
  {renderPopoverContent(measuredWidthObject)}
@@ -665,12 +667,12 @@ const PrimitiveInputField = ({
665
667
  style={memoizedStyles}
666
668
  id={id}
667
669
  className={cx(
668
- "flex w-0 flex-1 relative border-none outline-none min-w-0 self-stretch rounded py-1 bg-input-background select-all pointer-events-[all] focus:ring-2 focus:ring-primary font-sans font-normal text-heading5 placeholder:text-text-disabled focus:z-interactable transition-all",
670
+ "n-flex n-w-0 n-flex-1 n-relative n-border-none n-outline-none n-min-w-0 n-self-stretch n-rounded n-py-1 n-bg-input-background n-select-all n-pointer-events-[all] focus:n-ring-2 focus:n-ring-primary n-font-sans n-font-normal n-text-heading5 placeholder:n-text-text-disabled focus:n-z-interactable n-transition-[box-shadow]",
669
671
  readOnly
670
- ? "text-text-muted"
672
+ ? "n-text-text-muted"
671
673
  : disabled
672
- ? "text-text-disabled"
673
- : "text-text",
674
+ ? "n-text-text-disabled"
675
+ : "n-text-text",
674
676
  className
675
677
  )}
676
678
  {...props}
@@ -43,14 +43,14 @@ export const InspectorContainer = memo(
43
43
  {header}
44
44
  {children ? (
45
45
  <ScrollArea>
46
- <div className="flex flex-col relative">
46
+ <div className="n-flex n-flex-col n-relative">
47
47
  {showDividers
48
48
  ? withSeparatorElements(children, <Divider />)
49
49
  : children}
50
50
  </div>
51
51
  </ScrollArea>
52
52
  ) : fallback ? (
53
- <div className="flex flex-col relative h-full">{fallback}</div>
53
+ <div className="n-flex n-flex-col n-relative n-h-full">{fallback}</div>
54
54
  ) : null}
55
55
  </div>
56
56
  );