@noya-app/noya-designsystem 0.1.41 → 0.1.43
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 +10 -10
- package/CHANGELOG.md +16 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +268 -147
- package/dist/index.d.ts +268 -147
- package/dist/index.js +7618 -6908
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6161 -5487
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -5
- package/src/__tests__/combobox.test.ts +578 -0
- package/src/components/ActivityIndicator.tsx +4 -4
- package/src/components/AnimatePresence.tsx +5 -5
- package/src/components/Avatar.tsx +5 -2
- package/src/components/BaseToolbar.tsx +61 -0
- package/src/components/Button.tsx +1 -1
- package/src/components/Checkbox.tsx +6 -5
- package/src/components/Combobox.tsx +327 -337
- package/src/components/ComboboxMenu.tsx +88 -0
- package/src/components/Dialog.tsx +10 -6
- package/src/components/DimensionInput.tsx +4 -4
- package/src/components/FillPreviewBackground.tsx +51 -44
- package/src/components/FloatingWindow.tsx +5 -2
- package/src/components/GradientPicker.tsx +14 -14
- package/src/components/IconButton.tsx +6 -12
- package/src/components/Icons.tsx +3 -3
- package/src/components/InputField.tsx +145 -160
- package/src/components/Label.tsx +4 -4
- package/src/components/LabeledElementView.tsx +35 -41
- package/src/components/ListView.tsx +49 -39
- package/src/components/Message.tsx +75 -0
- package/src/components/Progress.tsx +2 -2
- package/src/components/ScrollArea.tsx +7 -5
- package/src/components/SegmentedControl.tsx +171 -0
- package/src/components/SelectMenu.tsx +61 -10
- package/src/components/Slider.tsx +5 -2
- package/src/components/Sortable.tsx +17 -27
- package/src/components/Spacer.tsx +28 -9
- package/src/components/Switch.tsx +8 -8
- package/src/components/TextArea.tsx +59 -12
- package/src/components/Toolbar.tsx +129 -0
- package/src/components/Tooltip.tsx +10 -7
- package/src/components/WorkspaceLayout.tsx +145 -152
- package/src/components/internal/Menu.tsx +5 -4
- package/src/contexts/DesignSystemConfiguration.tsx +15 -24
- package/src/contexts/DialogContext.tsx +137 -49
- package/src/contexts/ImageDataContext.tsx +6 -12
- package/src/index.css +1 -3
- package/src/index.tsx +12 -3
- package/src/utils/combobox.ts +369 -0
- package/tailwind.config.ts +1 -2
- package/src/components/RadioGroup.tsx +0 -100
- package/src/utils/completions.ts +0 -21
|
@@ -36,37 +36,60 @@ export type DialogContextValue = {
|
|
|
36
36
|
}
|
|
37
37
|
): Promise<string | undefined>;
|
|
38
38
|
|
|
39
|
+
openConfirmationDialog(
|
|
40
|
+
options:
|
|
41
|
+
| string
|
|
42
|
+
| {
|
|
43
|
+
title: string;
|
|
44
|
+
description?: ReactNode;
|
|
45
|
+
}
|
|
46
|
+
): Promise<boolean>;
|
|
47
|
+
|
|
39
48
|
containsElement(element: HTMLElement): boolean;
|
|
40
49
|
};
|
|
41
50
|
|
|
42
51
|
const DialogContext = createContext<DialogContextValue | undefined>(undefined);
|
|
43
52
|
|
|
53
|
+
type InputDialogContents = {
|
|
54
|
+
type: "input";
|
|
55
|
+
title: string;
|
|
56
|
+
description?: ReactNode;
|
|
57
|
+
placeholder?: string;
|
|
58
|
+
inputValue: string;
|
|
59
|
+
resolve: (value: string | undefined) => void;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type ConfirmationDialogContents = {
|
|
63
|
+
type: "confirmation";
|
|
64
|
+
title: string;
|
|
65
|
+
description?: ReactNode;
|
|
66
|
+
resolve: (value: boolean) => void;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
type DialogContents = InputDialogContents | ConfirmationDialogContents;
|
|
70
|
+
|
|
44
71
|
export const DialogProvider = function DialogProvider({
|
|
45
72
|
children,
|
|
46
73
|
}: {
|
|
47
74
|
children: ReactNode;
|
|
48
75
|
}) {
|
|
49
|
-
const [contents, setContents] = useState<
|
|
50
|
-
| {
|
|
51
|
-
title: string;
|
|
52
|
-
description?: ReactNode;
|
|
53
|
-
placeholder?: string;
|
|
54
|
-
inputValue: string;
|
|
55
|
-
resolve: (value: string | undefined) => void;
|
|
56
|
-
}
|
|
57
|
-
| undefined
|
|
58
|
-
>();
|
|
76
|
+
const [contents, setContents] = useState<DialogContents | undefined>();
|
|
59
77
|
|
|
60
78
|
const isOpen = !!contents;
|
|
61
79
|
|
|
62
80
|
const close = useCallback(() => {
|
|
63
81
|
if (!contents) return;
|
|
64
82
|
|
|
65
|
-
contents.
|
|
83
|
+
if (contents.type === "input") {
|
|
84
|
+
contents.resolve(undefined);
|
|
85
|
+
} else {
|
|
86
|
+
contents.resolve(false);
|
|
87
|
+
}
|
|
88
|
+
setContents(undefined);
|
|
66
89
|
}, [contents]);
|
|
67
90
|
|
|
68
91
|
const submit = useCallback(() => {
|
|
69
|
-
if (!contents ||
|
|
92
|
+
if (!contents || contents.type !== "input") return;
|
|
70
93
|
|
|
71
94
|
contents.resolve(contents.inputValue);
|
|
72
95
|
setContents(undefined);
|
|
@@ -79,11 +102,12 @@ export const DialogProvider = function DialogProvider({
|
|
|
79
102
|
typeof options === "string" ? { title: options } : options;
|
|
80
103
|
|
|
81
104
|
setContents({
|
|
105
|
+
type: "input",
|
|
82
106
|
title,
|
|
83
107
|
description,
|
|
84
108
|
inputValue: initialValue ?? "",
|
|
85
109
|
placeholder,
|
|
86
|
-
resolve: (value) => {
|
|
110
|
+
resolve: (value: string | undefined) => {
|
|
87
111
|
resolve(value);
|
|
88
112
|
setContents(undefined);
|
|
89
113
|
},
|
|
@@ -92,6 +116,26 @@ export const DialogProvider = function DialogProvider({
|
|
|
92
116
|
return promise;
|
|
93
117
|
}, []);
|
|
94
118
|
|
|
119
|
+
const openConfirmation: DialogContextValue["openConfirmationDialog"] =
|
|
120
|
+
useCallback((options) => {
|
|
121
|
+
const { promise, resolve } = createDeferredPromise<boolean>();
|
|
122
|
+
|
|
123
|
+
const { title, description } =
|
|
124
|
+
typeof options === "string" ? { title: options } : options;
|
|
125
|
+
|
|
126
|
+
setContents({
|
|
127
|
+
type: "confirmation",
|
|
128
|
+
title,
|
|
129
|
+
description,
|
|
130
|
+
resolve: (value: boolean) => {
|
|
131
|
+
resolve(value);
|
|
132
|
+
setContents(undefined);
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return promise;
|
|
137
|
+
}, []);
|
|
138
|
+
|
|
95
139
|
const handleKeyDown = useCallback(
|
|
96
140
|
(event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
97
141
|
if (event.key !== "Enter") return;
|
|
@@ -117,8 +161,12 @@ export const DialogProvider = function DialogProvider({
|
|
|
117
161
|
<>
|
|
118
162
|
<DialogContext.Provider
|
|
119
163
|
value={useMemo(
|
|
120
|
-
() => ({
|
|
121
|
-
|
|
164
|
+
() => ({
|
|
165
|
+
openInputDialog: open,
|
|
166
|
+
openConfirmationDialog: openConfirmation,
|
|
167
|
+
containsElement,
|
|
168
|
+
}),
|
|
169
|
+
[containsElement, open, openConfirmation]
|
|
122
170
|
)}
|
|
123
171
|
>
|
|
124
172
|
{children}
|
|
@@ -136,43 +184,79 @@ export const DialogProvider = function DialogProvider({
|
|
|
136
184
|
},
|
|
137
185
|
[close]
|
|
138
186
|
)}
|
|
139
|
-
onOpenAutoFocus={useCallback(
|
|
140
|
-
event
|
|
141
|
-
|
|
187
|
+
onOpenAutoFocus={useCallback(
|
|
188
|
+
(event: Event) => {
|
|
189
|
+
event.stopPropagation();
|
|
190
|
+
event.preventDefault();
|
|
142
191
|
|
|
143
|
-
|
|
192
|
+
if (!contents || contents.type !== "input") return;
|
|
144
193
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
194
|
+
inputRef.current?.focus();
|
|
195
|
+
inputRef.current?.setSelectionRange(
|
|
196
|
+
0,
|
|
197
|
+
inputRef.current.value.length
|
|
198
|
+
);
|
|
199
|
+
},
|
|
200
|
+
[contents]
|
|
201
|
+
)}
|
|
148
202
|
>
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
203
|
+
{contents?.type === "confirmation" ? (
|
|
204
|
+
<div className="flex flex-1 flex-row items-center">
|
|
205
|
+
<Spacer.Horizontal />
|
|
206
|
+
<Button
|
|
207
|
+
onClick={() => {
|
|
208
|
+
contents.resolve(false);
|
|
209
|
+
setContents(undefined);
|
|
210
|
+
}}
|
|
211
|
+
>
|
|
212
|
+
Cancel
|
|
213
|
+
</Button>
|
|
214
|
+
<Spacer.Horizontal size={16} />
|
|
215
|
+
<Button
|
|
216
|
+
onClick={() => {
|
|
217
|
+
contents.resolve(true);
|
|
218
|
+
setContents(undefined);
|
|
219
|
+
}}
|
|
220
|
+
>
|
|
221
|
+
OK
|
|
222
|
+
</Button>
|
|
223
|
+
</div>
|
|
224
|
+
) : (
|
|
225
|
+
<>
|
|
226
|
+
<InputField.Root>
|
|
227
|
+
<InputField.Input
|
|
228
|
+
ref={inputRef}
|
|
229
|
+
placeholder={contents?.placeholder}
|
|
230
|
+
value={contents?.type === "input" ? contents.inputValue : ""}
|
|
231
|
+
onChange={(value: string) => {
|
|
232
|
+
setContents((contents) =>
|
|
233
|
+
contents?.type === "input"
|
|
234
|
+
? {
|
|
235
|
+
...contents,
|
|
236
|
+
inputValue: value,
|
|
237
|
+
}
|
|
238
|
+
: undefined
|
|
239
|
+
);
|
|
240
|
+
}}
|
|
241
|
+
onKeyDown={handleKeyDown}
|
|
242
|
+
/>
|
|
243
|
+
</InputField.Root>
|
|
244
|
+
<Spacer.Vertical size={20} />
|
|
245
|
+
<div className="flex flex-1 flex-row items-center">
|
|
246
|
+
<Spacer.Horizontal />
|
|
247
|
+
<Button onClick={close}>Cancel</Button>
|
|
248
|
+
<Spacer.Horizontal size={16} />
|
|
249
|
+
<Button
|
|
250
|
+
disabled={
|
|
251
|
+
!contents || contents.type !== "input" || !contents.inputValue
|
|
252
|
+
}
|
|
253
|
+
onClick={submit}
|
|
254
|
+
>
|
|
255
|
+
Submit
|
|
256
|
+
</Button>
|
|
257
|
+
</div>
|
|
258
|
+
</>
|
|
259
|
+
)}
|
|
176
260
|
</Dialog>
|
|
177
261
|
</>
|
|
178
262
|
);
|
|
@@ -195,3 +279,7 @@ export function useOpenInputDialog() {
|
|
|
195
279
|
export function useDialogContainsElement() {
|
|
196
280
|
return useDialog().containsElement;
|
|
197
281
|
}
|
|
282
|
+
|
|
283
|
+
export function useOpenConfirmationDialog() {
|
|
284
|
+
return useDialog().openConfirmationDialog;
|
|
285
|
+
}
|
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
import React
|
|
2
|
-
createContext,
|
|
3
|
-
memo,
|
|
4
|
-
ReactNode,
|
|
5
|
-
useContext,
|
|
6
|
-
useMemo,
|
|
7
|
-
} from "react";
|
|
1
|
+
import * as React from "react";
|
|
8
2
|
|
|
9
3
|
export type ImageDataContextValue = {
|
|
10
4
|
getImageData: (ref: string) => ArrayBuffer | undefined;
|
|
11
5
|
};
|
|
12
6
|
|
|
13
|
-
const ImageDataContext = createContext<ImageDataContextValue | undefined>(
|
|
7
|
+
const ImageDataContext = React.createContext<ImageDataContextValue | undefined>(
|
|
14
8
|
undefined
|
|
15
9
|
);
|
|
16
10
|
|
|
17
|
-
export const ImageDataProvider = memo(function ImageDataProvider({
|
|
11
|
+
export const ImageDataProvider = React.memo(function ImageDataProvider({
|
|
18
12
|
children,
|
|
19
13
|
getImageData,
|
|
20
14
|
}: {
|
|
21
|
-
children: ReactNode;
|
|
15
|
+
children: React.ReactNode;
|
|
22
16
|
getImageData?: (ref: string) => ArrayBuffer | undefined;
|
|
23
17
|
}) {
|
|
24
|
-
const contextValue = useMemo(
|
|
18
|
+
const contextValue = React.useMemo(
|
|
25
19
|
() => ({ getImageData: getImageData ?? (() => undefined) }),
|
|
26
20
|
[getImageData]
|
|
27
21
|
);
|
|
@@ -34,7 +28,7 @@ export const ImageDataProvider = memo(function ImageDataProvider({
|
|
|
34
28
|
});
|
|
35
29
|
|
|
36
30
|
export function useImageData(ref: string): ArrayBuffer | undefined {
|
|
37
|
-
const value = useContext(ImageDataContext);
|
|
31
|
+
const value = React.useContext(ImageDataContext);
|
|
38
32
|
|
|
39
33
|
if (!value) {
|
|
40
34
|
throw new Error("Missing ImageDataProvider");
|
package/src/index.css
CHANGED
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
--listview-editing-background: #fff;
|
|
40
40
|
--slider-thumb-background: white;
|
|
41
41
|
--slider-border: #9698ac;
|
|
42
|
-
--radio-group-background: white;
|
|
43
42
|
--mask: rgb(12, 193, 67);
|
|
44
43
|
--transparent-checker: rgba(255, 255, 255, 0.8);
|
|
45
44
|
--scrollbar: rgba(199, 199, 199, 0.8);
|
|
@@ -62,7 +61,7 @@
|
|
|
62
61
|
--icon: rgb(129, 131, 165);
|
|
63
62
|
--icon-selected: rgb(220, 220, 220);
|
|
64
63
|
--warning: rgb(251, 211, 0);
|
|
65
|
-
--
|
|
64
|
+
--segmented-control-item: rgb(139, 139, 139);
|
|
66
65
|
--dot: rgba(0, 0, 0, 0.25);
|
|
67
66
|
--row-highlight: #3390ff10;
|
|
68
67
|
--table-row-background: var(--background);
|
|
@@ -106,7 +105,6 @@
|
|
|
106
105
|
--listview-raised-background: rgba(181, 178, 255, 0.1);
|
|
107
106
|
--listview-editing-background: #000;
|
|
108
107
|
--slider-thumb-background: rgb(248, 248, 250);
|
|
109
|
-
--radio-group-background: rgba(181, 178, 255, 0.08);
|
|
110
108
|
--mask: rgb(102, 187, 106);
|
|
111
109
|
--transparent-checker: rgba(255, 255, 255, 0.3);
|
|
112
110
|
--scrollbar: rgba(199, 199, 199, 0.2);
|
package/src/index.tsx
CHANGED
|
@@ -6,6 +6,7 @@ export * from "./components/Button";
|
|
|
6
6
|
export * from "./components/Checkbox";
|
|
7
7
|
export * from "./components/Chip";
|
|
8
8
|
export * from "./components/Combobox";
|
|
9
|
+
export * from "./components/ComboboxMenu";
|
|
9
10
|
export * from "./components/ContextMenu";
|
|
10
11
|
export * from "./components/Dialog";
|
|
11
12
|
export * from "./components/Divider";
|
|
@@ -20,7 +21,11 @@ export * from "./components/IconButton";
|
|
|
20
21
|
export * from "./components/Icons";
|
|
21
22
|
export * from "./components/InputField";
|
|
22
23
|
export * from "./components/InspectorContainer";
|
|
23
|
-
export {
|
|
24
|
+
export {
|
|
25
|
+
KeyboardShortcut,
|
|
26
|
+
SEPARATOR_ITEM,
|
|
27
|
+
getKeyboardShortcutsForMenuItems,
|
|
28
|
+
} from "./components/internal/Menu";
|
|
24
29
|
export type {
|
|
25
30
|
ExtractMenuItemType,
|
|
26
31
|
MenuItem,
|
|
@@ -29,10 +34,11 @@ export type {
|
|
|
29
34
|
export * from "./components/Label";
|
|
30
35
|
export * from "./components/LabeledElementView";
|
|
31
36
|
export * from "./components/ListView";
|
|
37
|
+
export * from "./components/Message";
|
|
32
38
|
export * from "./components/Popover";
|
|
33
39
|
export * from "./components/Progress";
|
|
34
|
-
export * from "./components/RadioGroup";
|
|
35
40
|
export * from "./components/ScrollArea";
|
|
41
|
+
export * from "./components/SegmentedControl";
|
|
36
42
|
export * from "./components/SelectMenu";
|
|
37
43
|
export * from "./components/Slider";
|
|
38
44
|
export * from "./components/Sortable";
|
|
@@ -64,7 +70,7 @@ export * from "./utils/createSectionedMenu";
|
|
|
64
70
|
export * from "./utils/getGradientBackground";
|
|
65
71
|
// Utils
|
|
66
72
|
export * from "./utils/colorFromString";
|
|
67
|
-
export * from "./utils/
|
|
73
|
+
export * from "./utils/combobox";
|
|
68
74
|
export * from "./utils/fuzzyScorer";
|
|
69
75
|
export * from "./utils/sketchColor";
|
|
70
76
|
export * from "./utils/sketchPattern";
|
|
@@ -73,3 +79,6 @@ export { default as withSeparatorElements } from "./utils/withSeparatorElements"
|
|
|
73
79
|
// Avoid dependency cycles
|
|
74
80
|
export * from "./components/DimensionInput";
|
|
75
81
|
export * as InspectorPrimitives from "./components/InspectorPrimitives";
|
|
82
|
+
|
|
83
|
+
export * from "./components/BaseToolbar";
|
|
84
|
+
export * from "./components/Toolbar";
|