@noya-app/noya-designsystem 0.1.44 → 0.1.46

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 (51) hide show
  1. package/.turbo/turbo-build.log +13 -10
  2. package/CHANGELOG.md +18 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +1194 -878
  5. package/dist/index.d.ts +1194 -878
  6. package/dist/index.js +11432 -10219
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +11556 -10360
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +4 -4
  11. package/src/__tests__/combobox.test.ts +137 -89
  12. package/src/components/AnimatePresence.tsx +10 -1
  13. package/src/components/Avatar.tsx +2 -0
  14. package/src/components/Breadcrumbs.tsx +29 -0
  15. package/src/components/Checkbox.tsx +6 -1
  16. package/src/components/Collection.tsx +74 -0
  17. package/src/components/Combobox.tsx +75 -56
  18. package/src/components/ComboboxMenu.tsx +61 -28
  19. package/src/components/CommandPalette.tsx +69 -0
  20. package/src/components/ContextMenu.tsx +33 -134
  21. package/src/components/DropdownMenu.tsx +46 -155
  22. package/src/components/EditableText.tsx +203 -0
  23. package/src/components/Fade.tsx +62 -0
  24. package/src/components/Grid.tsx +243 -0
  25. package/src/components/GridView.tsx +86 -96
  26. package/src/components/InputField.tsx +109 -133
  27. package/src/components/Label.tsx +81 -7
  28. package/src/components/LabeledField.tsx +112 -0
  29. package/src/components/List.tsx +268 -0
  30. package/src/components/ListView.tsx +65 -61
  31. package/src/components/Popover.tsx +12 -1
  32. package/src/components/SearchCompletionMenu.tsx +210 -0
  33. package/src/components/SegmentedControl.tsx +12 -6
  34. package/src/components/SelectMenu.tsx +110 -126
  35. package/src/components/Slider.tsx +18 -26
  36. package/src/components/Text.tsx +1 -0
  37. package/src/components/TextArea.tsx +4 -1
  38. package/src/components/Toolbar.tsx +9 -4
  39. package/src/components/TreeView.tsx +4 -0
  40. package/src/components/WorkspaceLayout.tsx +64 -20
  41. package/src/components/internal/Menu.tsx +107 -18
  42. package/src/components/internal/MenuViewport.tsx +152 -0
  43. package/src/components/internal/SelectItem.tsx +111 -0
  44. package/src/hooks/useIndent.ts +12 -0
  45. package/src/hooks/useLabel.ts +51 -0
  46. package/src/hooks/usePreservePanelSize.tsx +50 -19
  47. package/src/index.tsx +15 -6
  48. package/src/utils/combobox.ts +116 -101
  49. package/src/utils/createSectionedMenu.ts +11 -14
  50. package/src/utils/fuzzyScorer.ts +11 -8
  51. package/src/utils/selection.ts +48 -0
@@ -0,0 +1,111 @@
1
+ import { renderIcon } from "../Icons";
2
+
3
+ import { CheckIcon } from "@noya-app/noya-icons";
4
+ import * as Select from "@radix-ui/react-select";
5
+ import React, { useCallback } from "react";
6
+ import { Spacer } from "../Spacer";
7
+ import {
8
+ CHECKBOX_RIGHT_INSET,
9
+ CHECKBOX_WIDTH,
10
+ KeyboardShortcut,
11
+ styles,
12
+ } from "./Menu";
13
+ import { MenuComponents } from "./MenuViewport";
14
+
15
+ export const SelectItem = React.forwardRef(
16
+ (
17
+ {
18
+ children,
19
+ icon,
20
+ disabled,
21
+ checked,
22
+ Components,
23
+ value,
24
+ onSelect,
25
+ shortcut,
26
+ indented,
27
+ ...props
28
+ }: Select.SelectItemProps & {
29
+ icon?: React.ReactNode;
30
+ checked?: boolean | "indeterminate";
31
+ Components: MenuComponents;
32
+ onSelect?: (value: any) => void;
33
+ shortcut?: string;
34
+ indented?: boolean;
35
+ },
36
+ forwardedRef: React.ForwardedRef<HTMLDivElement>
37
+ ) => {
38
+ const handleSelectItem = useCallback(() => {
39
+ if (!value) return;
40
+ onSelect?.(value);
41
+ }, [onSelect, value]);
42
+
43
+ if (checked && Components.CheckboxItem) {
44
+ return (
45
+ <Components.CheckboxItem
46
+ checked={checked}
47
+ disabled={disabled}
48
+ onSelect={handleSelectItem}
49
+ className={styles.itemStyle({ disabled })}
50
+ >
51
+ {Components.ItemIndicator && (
52
+ <Components.ItemIndicator className={styles.itemIndicatorStyle}>
53
+ <CheckIcon />
54
+ </Components.ItemIndicator>
55
+ )}
56
+ {icon && (
57
+ <>
58
+ {renderIcon(icon)}
59
+ <Spacer.Horizontal size={8} />
60
+ </>
61
+ )}
62
+ {children}
63
+ {shortcut && (
64
+ <>
65
+ <Spacer.Horizontal />
66
+ <Spacer.Horizontal size={24} />
67
+ <KeyboardShortcut shortcut={shortcut} />
68
+ </>
69
+ )}
70
+ </Components.CheckboxItem>
71
+ );
72
+ }
73
+
74
+ return (
75
+ <div className="px-1">
76
+ <Components.Item
77
+ className={styles.itemStyle({ disabled })}
78
+ disabled={disabled}
79
+ value={value}
80
+ ref={forwardedRef}
81
+ onSelect={handleSelectItem}
82
+ {...props}
83
+ >
84
+ <div className="flex flex-1 items-center">
85
+ {checked ? (
86
+ <div className={styles.itemIndicatorStyle}>
87
+ <CheckIcon />
88
+ </div>
89
+ ) : indented ? (
90
+ <Spacer.Horizontal size={CHECKBOX_WIDTH - CHECKBOX_RIGHT_INSET} />
91
+ ) : null}
92
+ {icon && (
93
+ <>
94
+ {renderIcon(icon)}
95
+ <Spacer.Horizontal size={8} />
96
+ </>
97
+ )}
98
+ <Components.ItemText>{children}</Components.ItemText>
99
+ {shortcut && (
100
+ <>
101
+ <Spacer.Horizontal />
102
+ <Spacer.Horizontal size={24} />
103
+ <KeyboardShortcut shortcut={shortcut} />
104
+ </>
105
+ )}
106
+ </div>
107
+ </Components.Item>
108
+ </div>
109
+ );
110
+ }
111
+ );
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+
3
+ export const IndentContext = React.createContext<{
4
+ indentLevel: number;
5
+ }>({
6
+ indentLevel: 0,
7
+ });
8
+
9
+ export const useIndent = () => {
10
+ const { indentLevel } = React.useContext(IndentContext);
11
+ return indentLevel;
12
+ };
@@ -0,0 +1,51 @@
1
+ import React, { ReactNode } from "react";
2
+ import { LabelPosition } from "../components/Label";
3
+
4
+ export const LabelContext = React.createContext<{
5
+ fieldId?: string;
6
+ label?: React.ReactNode;
7
+ }>({
8
+ fieldId: "",
9
+ label: undefined,
10
+ });
11
+
12
+ type UseLabelParams = {
13
+ label?: ReactNode;
14
+ fieldId?: string;
15
+ };
16
+
17
+ export const useLabel = ({ label, fieldId }: UseLabelParams) => {
18
+ const { label: labelFromContext, fieldId: fieldIdFromContext } =
19
+ React.useContext(LabelContext);
20
+
21
+ return {
22
+ label: label ?? labelFromContext,
23
+ fieldId: fieldId ?? fieldIdFromContext,
24
+ };
25
+ };
26
+
27
+ export const LabelPositionContext =
28
+ React.createContext<LabelPositionContextValue>({
29
+ position: "start",
30
+ });
31
+
32
+ export const useLabelPosition = () => {
33
+ const { position } = React.useContext(LabelPositionContext);
34
+ return position;
35
+ };
36
+
37
+ export type LabelPositionContextValue = {
38
+ position: LabelPosition;
39
+ };
40
+
41
+ export type LabelWidthContextValue = {
42
+ width: number;
43
+ };
44
+ export const LabelWidthContext = React.createContext<LabelWidthContextValue>({
45
+ width: 100,
46
+ });
47
+
48
+ export const useLabelWidth = () => {
49
+ const { width } = React.useContext(LabelWidthContext);
50
+ return width;
51
+ };
@@ -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
@@ -2,42 +2,48 @@
2
2
  export * from "./components/ActivityIndicator";
3
3
  export * from "./components/AnimatePresence";
4
4
  export * from "./components/Avatar";
5
+ export * from "./components/Breadcrumbs";
5
6
  export * from "./components/Button";
6
7
  export * from "./components/Checkbox";
7
8
  export * from "./components/Chip";
9
+ export * from "./components/Collection";
8
10
  export * from "./components/Combobox";
9
11
  export * from "./components/ComboboxMenu";
12
+ export * from "./components/CommandPalette";
10
13
  export * from "./components/ContextMenu";
11
14
  export * from "./components/Dialog";
12
15
  export * from "./components/Divider";
13
16
  export * from "./components/DraggableMenuButton";
14
17
  export * from "./components/DropdownMenu";
18
+ export * from "./components/EditableText";
19
+ export * from "./components/Fade";
15
20
  export * from "./components/FillInputField";
16
21
  export * from "./components/FillPreviewBackground";
17
22
  export * from "./components/FloatingWindow";
18
23
  export * from "./components/GradientPicker";
24
+ export * from "./components/Grid";
19
25
  export * from "./components/GridView";
20
26
  export * from "./components/IconButton";
21
27
  export * from "./components/Icons";
22
28
  export * from "./components/InputField";
23
29
  export * from "./components/InspectorContainer";
24
- export {
25
- KeyboardShortcut,
26
- SEPARATOR_ITEM,
27
- getKeyboardShortcutsForMenuItems,
28
- } from "./components/internal/Menu";
30
+ export * from "./components/internal/Menu";
29
31
  export type {
30
32
  ExtractMenuItemType,
31
33
  MenuItem,
32
- RegularMenuItem,
34
+ SelectableMenuItem,
33
35
  } from "./components/internal/Menu";
36
+ export * from "./components/internal/MenuViewport";
34
37
  export * from "./components/Label";
35
38
  export * from "./components/LabeledElementView";
39
+ export * from "./components/LabeledField";
40
+ export * from "./components/List";
36
41
  export * from "./components/ListView";
37
42
  export * from "./components/Message";
38
43
  export * from "./components/Popover";
39
44
  export * from "./components/Progress";
40
45
  export * from "./components/ScrollArea";
46
+ export * from "./components/SearchCompletionMenu";
41
47
  export * from "./components/SegmentedControl";
42
48
  export * from "./components/SelectMenu";
43
49
  export * from "./components/Slider";
@@ -60,6 +66,8 @@ export * from "./contexts/GlobalInputBlurContext";
60
66
  export * from "./contexts/ImageDataContext";
61
67
  // Hooks
62
68
  export * from "./hooks/useHover";
69
+ export * from "./hooks/useIndent";
70
+ export * from "./hooks/useLabel";
63
71
  export * from "./hooks/usePlatform";
64
72
  export * from "./hooks/usePreservePanelSize";
65
73
  export * from "./hooks/useTheme";
@@ -72,6 +80,7 @@ export * from "./utils/getGradientBackground";
72
80
  export * from "./utils/colorFromString";
73
81
  export * from "./utils/combobox";
74
82
  export * from "./utils/fuzzyScorer";
83
+ export * from "./utils/selection";
75
84
  export * from "./utils/sketchColor";
76
85
  export * from "./utils/sketchPattern";
77
86
  export { default as withSeparatorElements } from "./utils/withSeparatorElements";