@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.
- package/.turbo/turbo-build.log +13 -10
- package/CHANGELOG.md +18 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +1194 -878
- package/dist/index.d.ts +1194 -878
- package/dist/index.js +11432 -10219
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11556 -10360
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/combobox.test.ts +137 -89
- package/src/components/AnimatePresence.tsx +10 -1
- package/src/components/Avatar.tsx +2 -0
- package/src/components/Breadcrumbs.tsx +29 -0
- package/src/components/Checkbox.tsx +6 -1
- package/src/components/Collection.tsx +74 -0
- package/src/components/Combobox.tsx +75 -56
- package/src/components/ComboboxMenu.tsx +61 -28
- package/src/components/CommandPalette.tsx +69 -0
- package/src/components/ContextMenu.tsx +33 -134
- package/src/components/DropdownMenu.tsx +46 -155
- package/src/components/EditableText.tsx +203 -0
- package/src/components/Fade.tsx +62 -0
- package/src/components/Grid.tsx +243 -0
- package/src/components/GridView.tsx +86 -96
- package/src/components/InputField.tsx +109 -133
- package/src/components/Label.tsx +81 -7
- package/src/components/LabeledField.tsx +112 -0
- package/src/components/List.tsx +268 -0
- package/src/components/ListView.tsx +65 -61
- package/src/components/Popover.tsx +12 -1
- package/src/components/SearchCompletionMenu.tsx +210 -0
- package/src/components/SegmentedControl.tsx +12 -6
- package/src/components/SelectMenu.tsx +110 -126
- package/src/components/Slider.tsx +18 -26
- package/src/components/Text.tsx +1 -0
- package/src/components/TextArea.tsx +4 -1
- package/src/components/Toolbar.tsx +9 -4
- package/src/components/TreeView.tsx +4 -0
- package/src/components/WorkspaceLayout.tsx +64 -20
- package/src/components/internal/Menu.tsx +107 -18
- package/src/components/internal/MenuViewport.tsx +152 -0
- package/src/components/internal/SelectItem.tsx +111 -0
- package/src/hooks/useIndent.ts +12 -0
- package/src/hooks/useLabel.ts +51 -0
- package/src/hooks/usePreservePanelSize.tsx +50 -19
- package/src/index.tsx +15 -6
- package/src/utils/combobox.ts +116 -101
- package/src/utils/createSectionedMenu.ts +11 -14
- package/src/utils/fuzzyScorer.ts +11 -8
- 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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
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";
|