@noya-app/noya-designsystem 0.1.44 → 0.1.45

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 (44) hide show
  1. package/.turbo/turbo-build.log +13 -10
  2. package/CHANGELOG.md +9 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +320 -78
  5. package/dist/index.d.ts +320 -78
  6. package/dist/index.js +2113 -1374
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +2000 -1274
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +3 -3
  11. package/src/components/AnimatePresence.tsx +10 -1
  12. package/src/components/Avatar.tsx +2 -0
  13. package/src/components/Checkbox.tsx +6 -1
  14. package/src/components/Combobox.tsx +6 -4
  15. package/src/components/ComboboxMenu.tsx +30 -15
  16. package/src/components/CommandPalette.tsx +69 -0
  17. package/src/components/ContextMenu.tsx +33 -134
  18. package/src/components/DropdownMenu.tsx +47 -155
  19. package/src/components/Fade.tsx +62 -0
  20. package/src/components/InputField.tsx +109 -133
  21. package/src/components/Label.tsx +81 -7
  22. package/src/components/LabeledField.tsx +112 -0
  23. package/src/components/ListView.tsx +55 -52
  24. package/src/components/Popover.tsx +12 -1
  25. package/src/components/SearchCompletionMenu.tsx +206 -0
  26. package/src/components/SegmentedControl.tsx +5 -2
  27. package/src/components/SelectMenu.tsx +104 -124
  28. package/src/components/SidebarList.tsx +252 -0
  29. package/src/components/Slider.tsx +18 -26
  30. package/src/components/Text.tsx +1 -0
  31. package/src/components/TextArea.tsx +4 -1
  32. package/src/components/Toolbar.tsx +6 -2
  33. package/src/components/TreeView.tsx +3 -0
  34. package/src/components/WorkspaceLayout.tsx +38 -18
  35. package/src/components/internal/Menu.tsx +58 -10
  36. package/src/components/internal/MenuViewport.tsx +151 -0
  37. package/src/components/internal/SelectItem.tsx +111 -0
  38. package/src/hooks/useIndent.ts +12 -0
  39. package/src/hooks/useLabel.ts +51 -0
  40. package/src/hooks/usePreservePanelSize.tsx +50 -19
  41. package/src/index.tsx +12 -5
  42. package/src/utils/combobox.ts +4 -1
  43. package/src/utils/createSectionedMenu.ts +11 -8
  44. package/src/utils/selection.ts +36 -0
@@ -130,26 +130,57 @@ export function usePreservePanelSize(
130
130
  });
131
131
  }
132
132
  } else if (currentLayout.length === 2) {
133
- const leftSidebarWidth = (oldPanelPercentages[0] / 100) * oldWindowWidth;
134
-
135
- const newLeftSidebarPercentage =
136
- (leftSidebarWidth / windowSize.width) * 100;
137
-
138
- const newLayout = [
139
- newLeftSidebarPercentage,
140
- 100 - newLeftSidebarPercentage,
133
+ // Check if this is a right sidebar layout by looking at the panel IDs
134
+ const panelGroup = document.querySelector(
135
+ `[data-panel-group-id="${EDITOR_PANEL_GROUP_ID}"]`
136
+ );
137
+ const panels = [
138
+ ...(panelGroup?.querySelectorAll<HTMLElement>("[data-panel]") ?? []),
141
139
  ];
142
-
143
- try {
144
- panelGroupRef.current?.setLayout(newLayout);
145
- } catch (e) {
146
- console.error(e);
147
- console.info("snapshot on error", {
148
- oldWindowWidth,
149
- oldPanelPercentages,
150
- newLayout,
151
- currentLayout,
152
- });
140
+ const isRightSidebarLayout = panels[1]?.id === RIGHT_SIDEBAR_ID;
141
+
142
+ if (isRightSidebarLayout) {
143
+ const rightSidebarWidth =
144
+ (oldPanelPercentages[1] / 100) * oldWindowWidth;
145
+ const newRightSidebarPercentage =
146
+ (rightSidebarWidth / windowSize.width) * 100;
147
+ const newLayout = [
148
+ 100 - newRightSidebarPercentage,
149
+ newRightSidebarPercentage,
150
+ ];
151
+
152
+ try {
153
+ panelGroupRef.current?.setLayout(newLayout);
154
+ } catch (e) {
155
+ console.error(e);
156
+ console.info("snapshot on error", {
157
+ oldWindowWidth,
158
+ oldPanelPercentages,
159
+ newLayout,
160
+ currentLayout,
161
+ });
162
+ }
163
+ } else {
164
+ const leftSidebarWidth =
165
+ (oldPanelPercentages[0] / 100) * oldWindowWidth;
166
+ const newLeftSidebarPercentage =
167
+ (leftSidebarWidth / windowSize.width) * 100;
168
+ const newLayout = [
169
+ newLeftSidebarPercentage,
170
+ 100 - newLeftSidebarPercentage,
171
+ ];
172
+
173
+ try {
174
+ panelGroupRef.current?.setLayout(newLayout);
175
+ } catch (e) {
176
+ console.error(e);
177
+ console.info("snapshot on error", {
178
+ oldWindowWidth,
179
+ oldPanelPercentages,
180
+ newLayout,
181
+ currentLayout,
182
+ });
183
+ }
153
184
  }
154
185
  }
155
186
  }, [panelGroupRef, windowSize.width]);
package/src/index.tsx CHANGED
@@ -7,11 +7,13 @@ export * from "./components/Checkbox";
7
7
  export * from "./components/Chip";
8
8
  export * from "./components/Combobox";
9
9
  export * from "./components/ComboboxMenu";
10
+ export * from "./components/CommandPalette";
10
11
  export * from "./components/ContextMenu";
11
12
  export * from "./components/Dialog";
12
13
  export * from "./components/Divider";
13
14
  export * from "./components/DraggableMenuButton";
14
15
  export * from "./components/DropdownMenu";
16
+ export * from "./components/Fade";
15
17
  export * from "./components/FillInputField";
16
18
  export * from "./components/FillPreviewBackground";
17
19
  export * from "./components/FloatingWindow";
@@ -21,25 +23,27 @@ export * from "./components/IconButton";
21
23
  export * from "./components/Icons";
22
24
  export * from "./components/InputField";
23
25
  export * from "./components/InspectorContainer";
24
- export {
25
- KeyboardShortcut,
26
- SEPARATOR_ITEM,
27
- getKeyboardShortcutsForMenuItems,
28
- } from "./components/internal/Menu";
26
+ export * from "./components/internal/Menu";
29
27
  export type {
30
28
  ExtractMenuItemType,
31
29
  MenuItem,
32
30
  RegularMenuItem,
31
+ SectionHeaderMenuItem,
32
+ SeparatorItem,
33
33
  } from "./components/internal/Menu";
34
+ export * from "./components/internal/MenuViewport";
34
35
  export * from "./components/Label";
35
36
  export * from "./components/LabeledElementView";
37
+ export * from "./components/LabeledField";
36
38
  export * from "./components/ListView";
37
39
  export * from "./components/Message";
38
40
  export * from "./components/Popover";
39
41
  export * from "./components/Progress";
40
42
  export * from "./components/ScrollArea";
43
+ export * from "./components/SearchCompletionMenu";
41
44
  export * from "./components/SegmentedControl";
42
45
  export * from "./components/SelectMenu";
46
+ export * from "./components/SidebarList";
43
47
  export * from "./components/Slider";
44
48
  export * from "./components/Sortable";
45
49
  export type { RelativeDropPosition } from "./components/Sortable";
@@ -60,6 +64,8 @@ export * from "./contexts/GlobalInputBlurContext";
60
64
  export * from "./contexts/ImageDataContext";
61
65
  // Hooks
62
66
  export * from "./hooks/useHover";
67
+ export * from "./hooks/useIndent";
68
+ export * from "./hooks/useLabel";
63
69
  export * from "./hooks/usePlatform";
64
70
  export * from "./hooks/usePreservePanelSize";
65
71
  export * from "./hooks/useTheme";
@@ -72,6 +78,7 @@ export * from "./utils/getGradientBackground";
72
78
  export * from "./utils/colorFromString";
73
79
  export * from "./utils/combobox";
74
80
  export * from "./utils/fuzzyScorer";
81
+ export * from "./utils/selection";
75
82
  export * from "./utils/sketchColor";
76
83
  export * from "./utils/sketchPattern";
77
84
  export { default as withSeparatorElements } from "./utils/withSeparatorElements";
@@ -7,7 +7,10 @@ export type ComboboxOption = {
7
7
  id: string;
8
8
  name: string;
9
9
  icon?: ReactNode;
10
+ shortcut?: string;
11
+ disabled?: boolean;
10
12
  alwaysInclude?: boolean;
13
+ checked?: boolean;
11
14
  };
12
15
 
13
16
  export type ComboboxSectionHeader = {
@@ -326,7 +329,7 @@ function filterWithGroupedSections(
326
329
  return result;
327
330
  }
328
331
 
329
- function getNextIndex<T>(
332
+ export function getNextIndex<T>(
330
333
  items: T[],
331
334
  currentIndex: number,
332
335
  direction: "next" | "previous",
@@ -1,16 +1,19 @@
1
1
  import {
2
2
  MenuItem,
3
3
  RegularMenuItem,
4
- SEPARATOR_ITEM,
5
- } from '../components/internal/Menu';
4
+ SeparatorItem,
5
+ } from "../components/internal/Menu";
6
6
 
7
7
  export type Optional<T> = T | false | null | undefined;
8
8
 
9
- function withSeparators<T>(elements: T[], separator: T) {
10
- const result: T[] = [];
9
+ function withSeparators<T extends string>(
10
+ elements: RegularMenuItem<T>[][],
11
+ separator: SeparatorItem
12
+ ): MenuItem<T>[] {
13
+ const result: MenuItem<T>[] = [];
11
14
 
12
15
  for (let i = 0; i < elements.length; i++) {
13
- result.push(elements[i]);
16
+ result.push(...elements[i]);
14
17
 
15
18
  if (i !== elements.length - 1) {
16
19
  result.push(separator);
@@ -32,7 +35,7 @@ export function createSectionedMenu<T extends string>(
32
35
  .map((section) => section.flatMap((item) => (item ? [item] : [])))
33
36
  .filter((section) => section.length > 0);
34
37
 
35
- return withSeparators<MenuItem<T>[]>(nonEmptySections, [
36
- SEPARATOR_ITEM,
37
- ]).flat();
38
+ return withSeparators(nonEmptySections, {
39
+ type: "separator",
40
+ }).flat();
38
41
  }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Updates the selection state based on user interaction.
3
+ * Handles single selection, multi-selection with meta/ctrl, and range selection with shift.
4
+ */
5
+ export function updateSelection(
6
+ allIds: string[],
7
+ selectedIds: string[],
8
+ clickedId: string,
9
+ event?: { shiftKey?: boolean; metaKey?: boolean; ctrlKey?: boolean }
10
+ ): string[] {
11
+ const metaOrCtrl = event?.metaKey || event?.ctrlKey;
12
+
13
+ if (!event || (!event.shiftKey && !metaOrCtrl)) {
14
+ return [clickedId];
15
+ }
16
+
17
+ if (metaOrCtrl) {
18
+ const isSelected = selectedIds.includes(clickedId);
19
+ return isSelected
20
+ ? selectedIds.filter((id) => id !== clickedId)
21
+ : [...selectedIds, clickedId];
22
+ }
23
+
24
+ if (event.shiftKey && selectedIds.length > 0) {
25
+ const lastSelectedId = selectedIds[selectedIds.length - 1];
26
+ const lastSelectedIndex = allIds.indexOf(lastSelectedId);
27
+ const clickedIndex = allIds.indexOf(clickedId);
28
+
29
+ const start = Math.min(lastSelectedIndex, clickedIndex);
30
+ const end = Math.max(lastSelectedIndex, clickedIndex);
31
+
32
+ return allIds.slice(start, end + 1);
33
+ }
34
+
35
+ return [clickedId];
36
+ }