@noya-app/noya-designsystem 0.1.28 → 0.1.30
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 +8 -8
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +6 -22
- package/dist/index.d.ts +6 -22
- package/dist/index.js +74 -180
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +75 -180
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/GridView.tsx +37 -35
- package/src/components/InputField.tsx +3 -0
- package/src/components/ListView.tsx +1 -0
- package/src/components/RadioGroup.tsx +2 -0
- package/src/components/Switch.tsx +1 -0
- package/src/components/WorkspaceLayout.tsx +16 -2
- package/src/index.tsx +0 -1
- package/src/components/ArrayController.tsx +0 -168
package/package.json
CHANGED
|
@@ -64,39 +64,39 @@ const sizes: Record<
|
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
const Grid = styled.div<{
|
|
67
|
-
size: GridViewSize;
|
|
68
|
-
padding: CSSProperties["padding"];
|
|
69
|
-
}>(({ theme, size, padding }) => {
|
|
67
|
+
$size: GridViewSize;
|
|
68
|
+
$padding: CSSProperties["padding"];
|
|
69
|
+
}>(({ theme, $size, $padding }) => {
|
|
70
70
|
return {
|
|
71
71
|
color: theme.colors.text,
|
|
72
72
|
display: "grid",
|
|
73
|
-
gridTemplateColumns: `repeat(auto-fill, minmax(${sizes[size].itemWidth}px, 1fr))`,
|
|
73
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${sizes[$size].itemWidth}px, 1fr))`,
|
|
74
74
|
// gridAutoRows: `${sizes[size].itemHeight}px`,
|
|
75
|
-
gap: `${sizes[size].gap}px`,
|
|
75
|
+
gap: `${sizes[$size].gap}px`,
|
|
76
76
|
// gridTemplateColumns: `repeat(auto-fill, minmax(
|
|
77
77
|
// ${size === 'large' ? '280px' : size === 'small' ? '160px' : '116px'}
|
|
78
78
|
// , 1fr))`,
|
|
79
79
|
// gridAutoRows:
|
|
80
80
|
// size === 'large' ? '280px' : size === 'small' ? '170px' : '116px',
|
|
81
81
|
// gap: size === 'large' || size === 'small' ? `20px` : `12px`,
|
|
82
|
-
padding,
|
|
82
|
+
padding: $padding,
|
|
83
83
|
};
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
const Container = styled.div<{ scrollable: boolean }>(
|
|
87
|
-
({ theme, scrollable }) => ({
|
|
88
|
-
flex: scrollable ? "1" : "0 0 auto",
|
|
86
|
+
const Container = styled.div<{ $scrollable: boolean }>(
|
|
87
|
+
({ theme, $scrollable }) => ({
|
|
88
|
+
flex: $scrollable ? "1" : "0 0 auto",
|
|
89
89
|
display: "flex",
|
|
90
90
|
flexDirection: "column",
|
|
91
91
|
})
|
|
92
92
|
);
|
|
93
93
|
|
|
94
94
|
const ContentContainer = styled.div<{
|
|
95
|
-
selected?: boolean;
|
|
96
|
-
hovered?: boolean;
|
|
97
|
-
bordered: boolean;
|
|
98
|
-
disabled: boolean;
|
|
99
|
-
}>(({ theme, selected, hovered, bordered, disabled }) => ({
|
|
95
|
+
$selected?: boolean;
|
|
96
|
+
$hovered?: boolean;
|
|
97
|
+
$bordered: boolean;
|
|
98
|
+
$disabled: boolean;
|
|
99
|
+
}>(({ theme, $selected, $hovered, $bordered, $disabled }) => ({
|
|
100
100
|
display: "flex",
|
|
101
101
|
flex: "1",
|
|
102
102
|
backgroundColor: theme.colors.sidebar.background,
|
|
@@ -104,18 +104,18 @@ const ContentContainer = styled.div<{
|
|
|
104
104
|
justifyContent: "center",
|
|
105
105
|
borderRadius: "2px",
|
|
106
106
|
border: `1px solid ${
|
|
107
|
-
selected
|
|
107
|
+
$selected
|
|
108
108
|
? theme.colors.primary
|
|
109
109
|
: // : hovered
|
|
110
110
|
// ? `rgb(132, 63, 255, 0.5)`
|
|
111
|
-
bordered
|
|
111
|
+
$bordered
|
|
112
112
|
? theme.colors.divider
|
|
113
113
|
: "transparent"
|
|
114
114
|
}`,
|
|
115
115
|
overflow: "hidden",
|
|
116
116
|
|
|
117
117
|
cursor: "pointer",
|
|
118
|
-
...(disabled
|
|
118
|
+
...($disabled
|
|
119
119
|
? { opacity: 0.5 }
|
|
120
120
|
: {
|
|
121
121
|
"&:hover": { opacity: 0.85 },
|
|
@@ -134,8 +134,8 @@ const ItemContainer = styled.div(({ theme }) => ({
|
|
|
134
134
|
},
|
|
135
135
|
}));
|
|
136
136
|
|
|
137
|
-
const ItemTitle = styled.span<{ showBackground: boolean }>(
|
|
138
|
-
({ theme, showBackground }) => ({
|
|
137
|
+
const ItemTitle = styled.span<{ $showBackground: boolean }>(
|
|
138
|
+
({ theme, $showBackground }) => ({
|
|
139
139
|
...theme.textStyles.small,
|
|
140
140
|
lineHeight: "1",
|
|
141
141
|
color: theme.colors.text,
|
|
@@ -145,7 +145,7 @@ const ItemTitle = styled.span<{ showBackground: boolean }>(
|
|
|
145
145
|
overflow: "hidden",
|
|
146
146
|
textOverflow: "ellipsis",
|
|
147
147
|
|
|
148
|
-
...(showBackground && {
|
|
148
|
+
...($showBackground && {
|
|
149
149
|
background: theme.colors.sidebar.background,
|
|
150
150
|
// border: `1px solid ${theme.colors.dividerSubtle}`,
|
|
151
151
|
padding: "2px 4px",
|
|
@@ -155,8 +155,8 @@ const ItemTitle = styled.span<{ showBackground: boolean }>(
|
|
|
155
155
|
})
|
|
156
156
|
);
|
|
157
157
|
|
|
158
|
-
const ItemDescription = styled.span<{ showBackground: boolean }>(
|
|
159
|
-
({ theme, showBackground }) => ({
|
|
158
|
+
const ItemDescription = styled.span<{ $showBackground: boolean }>(
|
|
159
|
+
({ theme, $showBackground }) => ({
|
|
160
160
|
...theme.textStyles.small,
|
|
161
161
|
fontSize: "0.7rem",
|
|
162
162
|
lineHeight: "1",
|
|
@@ -166,7 +166,7 @@ const ItemDescription = styled.span<{ showBackground: boolean }>(
|
|
|
166
166
|
overflow: "hidden",
|
|
167
167
|
textOverflow: "ellipsis",
|
|
168
168
|
|
|
169
|
-
...(showBackground && {
|
|
169
|
+
...($showBackground && {
|
|
170
170
|
background: theme.colors.sidebar.background,
|
|
171
171
|
// border: `1px solid ${theme.colors.dividerSubtle}`,
|
|
172
172
|
padding: "2px 4px",
|
|
@@ -319,10 +319,10 @@ const GridViewItem = forwardRef(function GridViewItem<
|
|
|
319
319
|
onKeyDown={handleKeyDown}
|
|
320
320
|
>
|
|
321
321
|
<ContentContainer
|
|
322
|
-
disabled={disabled}
|
|
323
|
-
bordered={bordered}
|
|
324
|
-
selected={selected}
|
|
325
|
-
hovered={!disabled && hovered}
|
|
322
|
+
$disabled={disabled}
|
|
323
|
+
$bordered={bordered}
|
|
324
|
+
$selected={selected}
|
|
325
|
+
$hovered={!disabled && hovered}
|
|
326
326
|
onClick={handleClick}
|
|
327
327
|
onDoubleClick={onDoubleClick}
|
|
328
328
|
onContextMenu={onContextMenu}
|
|
@@ -333,17 +333,17 @@ const GridViewItem = forwardRef(function GridViewItem<
|
|
|
333
333
|
{textPosition === "below" && (
|
|
334
334
|
<>
|
|
335
335
|
<Spacer.Vertical size={8} />
|
|
336
|
-
<ItemTitle showBackground={false}>{title || " "}</ItemTitle>
|
|
337
|
-
<ItemDescription showBackground={false}>
|
|
336
|
+
<ItemTitle $showBackground={false}>{title || " "}</ItemTitle>
|
|
337
|
+
<ItemDescription $showBackground={false}>
|
|
338
338
|
{subtitle || " "}
|
|
339
339
|
</ItemDescription>
|
|
340
340
|
</>
|
|
341
341
|
)}
|
|
342
342
|
{textPosition === "overlay" && hovered && (title || subtitle) && (
|
|
343
343
|
<TextOverlay>
|
|
344
|
-
{title && <ItemTitle showBackground>{title}</ItemTitle>}
|
|
344
|
+
{title && <ItemTitle $showBackground>{title}</ItemTitle>}
|
|
345
345
|
{subtitle && (
|
|
346
|
-
<ItemDescription showBackground>{subtitle}</ItemDescription>
|
|
346
|
+
<ItemDescription $showBackground>{subtitle}</ItemDescription>
|
|
347
347
|
)}
|
|
348
348
|
</TextOverlay>
|
|
349
349
|
)}
|
|
@@ -368,8 +368,10 @@ const GridViewItem = forwardRef(function GridViewItem<
|
|
|
368
368
|
<Tooltip
|
|
369
369
|
content={
|
|
370
370
|
<Stack.V gap={2}>
|
|
371
|
-
<ItemTitle showBackground={false}>{title}</ItemTitle>
|
|
372
|
-
<ItemDescription showBackground={false}>
|
|
371
|
+
<ItemTitle $showBackground={false}>{title}</ItemTitle>
|
|
372
|
+
<ItemDescription $showBackground={false}>
|
|
373
|
+
{subtitle}
|
|
374
|
+
</ItemDescription>
|
|
373
375
|
</Stack.V>
|
|
374
376
|
}
|
|
375
377
|
>
|
|
@@ -432,7 +434,7 @@ function GridViewRoot({
|
|
|
432
434
|
|
|
433
435
|
return (
|
|
434
436
|
<GridViewContext.Provider value={contextValue}>
|
|
435
|
-
<Container onClick={handleClick} scrollable={scrollable}>
|
|
437
|
+
<Container onClick={handleClick} $scrollable={scrollable}>
|
|
436
438
|
{scrollable ? <ScrollArea>{children}</ScrollArea> : children}
|
|
437
439
|
</Container>
|
|
438
440
|
</GridViewContext.Provider>
|
|
@@ -449,7 +451,7 @@ function GridViewSection({
|
|
|
449
451
|
const { size } = useContext(GridViewContext);
|
|
450
452
|
|
|
451
453
|
return (
|
|
452
|
-
<Grid size={size} padding={padding}>
|
|
454
|
+
<Grid $size={size} $padding={padding}>
|
|
453
455
|
{children}
|
|
454
456
|
</Grid>
|
|
455
457
|
);
|
|
@@ -35,6 +35,7 @@ type InputFieldContextValue = {
|
|
|
35
35
|
labelSize: number;
|
|
36
36
|
hasLabel: boolean;
|
|
37
37
|
hasDropdown: boolean;
|
|
38
|
+
/** @default medium */
|
|
38
39
|
size: InputFieldSize;
|
|
39
40
|
isFocused: boolean;
|
|
40
41
|
onFocusChange: (isFocused: boolean) => void;
|
|
@@ -543,9 +544,11 @@ interface InputFieldRootProps {
|
|
|
543
544
|
flex?: string;
|
|
544
545
|
children?: ReactNode;
|
|
545
546
|
width?: number;
|
|
547
|
+
/** @default end */
|
|
546
548
|
labelPosition?: LabelPosition;
|
|
547
549
|
labelSize?: number;
|
|
548
550
|
hasDropdown?: boolean;
|
|
551
|
+
/** @default medium */
|
|
549
552
|
size?: InputFieldSize;
|
|
550
553
|
renderPopoverContent?: (options: { width: number }) => ReactNode;
|
|
551
554
|
onFocusChange?: (isFocused: boolean) => void;
|
|
@@ -108,6 +108,7 @@ const ToggleGroupItem = forwardRef(function ToggleGroupItem(
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
type RadioGroupContextValue = {
|
|
111
|
+
/** @default primary */
|
|
111
112
|
colorScheme?: RadioGroupColorScheme;
|
|
112
113
|
};
|
|
113
114
|
|
|
@@ -119,6 +120,7 @@ interface Props {
|
|
|
119
120
|
id?: string;
|
|
120
121
|
value?: string;
|
|
121
122
|
onValueChange?: (value: string) => void;
|
|
123
|
+
/** @default primary */
|
|
122
124
|
colorScheme?: RadioGroupColorScheme;
|
|
123
125
|
allowEmpty?: boolean;
|
|
124
126
|
children: ReactNode;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
DesignSystemThemeProvider,
|
|
3
|
+
useDesignSystemTheme,
|
|
4
|
+
} from "@noya-app/noya-designsystem";
|
|
2
5
|
import { useKeyboardShortcuts } from "@noya-app/noya-keymap";
|
|
3
6
|
import React, { forwardRef, useImperativeHandle, useRef } from "react";
|
|
4
7
|
import {
|
|
@@ -54,7 +57,7 @@ export type IWorkspaceLayout = {
|
|
|
54
57
|
toggleRightSidebar: () => void;
|
|
55
58
|
};
|
|
56
59
|
|
|
57
|
-
|
|
60
|
+
const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
|
|
58
61
|
{
|
|
59
62
|
autoSavePrefix,
|
|
60
63
|
leftSidebarContent: leftPanelContent,
|
|
@@ -260,3 +263,14 @@ export const WorkspaceLayout = forwardRef(function WorkspaceLayout(
|
|
|
260
263
|
</div>
|
|
261
264
|
);
|
|
262
265
|
});
|
|
266
|
+
|
|
267
|
+
export const WorkspaceLayout = forwardRef(function WorkspaceLayout(
|
|
268
|
+
props: Props,
|
|
269
|
+
forwardedRef: React.ForwardedRef<IWorkspaceLayout>
|
|
270
|
+
) {
|
|
271
|
+
return (
|
|
272
|
+
<DesignSystemThemeProvider>
|
|
273
|
+
<WorkspaceLayoutWithTheme {...props} ref={forwardedRef} />
|
|
274
|
+
</DesignSystemThemeProvider>
|
|
275
|
+
);
|
|
276
|
+
});
|
package/src/index.tsx
CHANGED
|
@@ -84,6 +84,5 @@ export * from "./utils/sketchPattern";
|
|
|
84
84
|
export { default as withSeparatorElements } from "./utils/withSeparatorElements";
|
|
85
85
|
|
|
86
86
|
// Avoid dependency cycles
|
|
87
|
-
export * from "./components/ArrayController";
|
|
88
87
|
export * from "./components/DimensionInput";
|
|
89
88
|
export * as InspectorPrimitives from "./components/InspectorPrimitives";
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { range } from "@noya-app/noya-utils";
|
|
2
|
-
import React, { ReactNode, memo, useCallback, useMemo } from "react";
|
|
3
|
-
import styled, { useTheme } from "styled-components";
|
|
4
|
-
import withSeparatorElements from "../utils/withSeparatorElements";
|
|
5
|
-
import { Button } from "./Button";
|
|
6
|
-
import { IconButton } from "./IconButton";
|
|
7
|
-
import * as InspectorPrimitives from "./InspectorPrimitives";
|
|
8
|
-
import { ListView } from "./ListView";
|
|
9
|
-
import { RelativeDropPosition, Sortable } from "./Sortable";
|
|
10
|
-
import { Spacer } from "./Spacer";
|
|
11
|
-
import { Stack } from "./Stack";
|
|
12
|
-
|
|
13
|
-
const ElementRow = styled.div({
|
|
14
|
-
flex: "0 0 auto",
|
|
15
|
-
display: "flex",
|
|
16
|
-
flexDirection: "row",
|
|
17
|
-
alignItems: "center",
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const ItemContainer = styled.div({
|
|
21
|
-
position: "relative",
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export interface ArrayControllerProps<Item> {
|
|
25
|
-
id: string;
|
|
26
|
-
items: Item[];
|
|
27
|
-
title: ReactNode;
|
|
28
|
-
sortable?: boolean;
|
|
29
|
-
reversed?: boolean;
|
|
30
|
-
expanded?: boolean;
|
|
31
|
-
getKey?: (item: Item) => string;
|
|
32
|
-
onMoveItem?: (sourceIndex: number, destinationIndex: number) => void;
|
|
33
|
-
onClickPlus?: () => void;
|
|
34
|
-
onClickTrash?: () => void;
|
|
35
|
-
onClickExpand?: () => void;
|
|
36
|
-
renderItem: (props: { item: Item; index: number }) => ReactNode;
|
|
37
|
-
renderExpandedContent?: () => ReactNode;
|
|
38
|
-
padding?: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const ArrayController = memo(function ArrayController<Item>({
|
|
42
|
-
id,
|
|
43
|
-
items,
|
|
44
|
-
title,
|
|
45
|
-
sortable = false,
|
|
46
|
-
reversed = true,
|
|
47
|
-
expanded = false,
|
|
48
|
-
getKey,
|
|
49
|
-
onMoveItem,
|
|
50
|
-
onClickPlus,
|
|
51
|
-
onClickTrash,
|
|
52
|
-
onClickExpand,
|
|
53
|
-
renderItem,
|
|
54
|
-
renderExpandedContent,
|
|
55
|
-
padding = 10,
|
|
56
|
-
}: ArrayControllerProps<Item>) {
|
|
57
|
-
const iconColor = useTheme().colors.icon;
|
|
58
|
-
const primaryLightColor = useTheme().colors.primaryLight;
|
|
59
|
-
|
|
60
|
-
const keys = useMemo(
|
|
61
|
-
() => items.map((item, index) => getKey?.(item) ?? index.toString()),
|
|
62
|
-
[getKey, items]
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const indexes = reversed
|
|
66
|
-
? range(0, items.length).reverse()
|
|
67
|
-
: range(0, items.length);
|
|
68
|
-
|
|
69
|
-
const handleMoveItem = useCallback(
|
|
70
|
-
(
|
|
71
|
-
sourceIndex: number,
|
|
72
|
-
destinationIndex: number,
|
|
73
|
-
position: RelativeDropPosition
|
|
74
|
-
) => {
|
|
75
|
-
if (reversed) {
|
|
76
|
-
if (position === "above") {
|
|
77
|
-
position = "below";
|
|
78
|
-
} else if (position === "below") {
|
|
79
|
-
position = "above";
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
onMoveItem?.(
|
|
84
|
-
sourceIndex,
|
|
85
|
-
position === "below" ? destinationIndex + 1 : destinationIndex
|
|
86
|
-
);
|
|
87
|
-
},
|
|
88
|
-
[onMoveItem, reversed]
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
const renderRow = (index: number) => {
|
|
92
|
-
return (
|
|
93
|
-
<ElementRow key={keys[index]}>
|
|
94
|
-
{renderItem({ item: items[index], index: index })}
|
|
95
|
-
</ElementRow>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<InspectorPrimitives.Section id={id} $padding={padding} $gap="2px">
|
|
101
|
-
<InspectorPrimitives.SectionHeader>
|
|
102
|
-
<Button variant="none" onClick={onClickPlus}>
|
|
103
|
-
<InspectorPrimitives.Title>{title}</InspectorPrimitives.Title>
|
|
104
|
-
</Button>
|
|
105
|
-
<Spacer.Horizontal />
|
|
106
|
-
{withSeparatorElements(
|
|
107
|
-
[
|
|
108
|
-
onClickTrash && (
|
|
109
|
-
<IconButton
|
|
110
|
-
id={`${id}-trash`}
|
|
111
|
-
iconName="TrashIcon"
|
|
112
|
-
color={iconColor}
|
|
113
|
-
onClick={onClickTrash}
|
|
114
|
-
/>
|
|
115
|
-
),
|
|
116
|
-
onClickExpand && (
|
|
117
|
-
<IconButton
|
|
118
|
-
id={`${id}-gear`}
|
|
119
|
-
iconName="GearIcon"
|
|
120
|
-
color={expanded ? primaryLightColor : iconColor}
|
|
121
|
-
onClick={onClickExpand}
|
|
122
|
-
/>
|
|
123
|
-
),
|
|
124
|
-
onClickPlus && (
|
|
125
|
-
<IconButton
|
|
126
|
-
id={`${id}-add`}
|
|
127
|
-
iconName="PlusIcon"
|
|
128
|
-
color={iconColor}
|
|
129
|
-
onClick={onClickPlus}
|
|
130
|
-
/>
|
|
131
|
-
),
|
|
132
|
-
],
|
|
133
|
-
<Spacer.Horizontal size={8} />
|
|
134
|
-
)}
|
|
135
|
-
</InspectorPrimitives.SectionHeader>
|
|
136
|
-
<Stack.V gap="4px">
|
|
137
|
-
{sortable ? (
|
|
138
|
-
<Sortable.Root
|
|
139
|
-
keys={keys}
|
|
140
|
-
renderOverlay={renderRow}
|
|
141
|
-
onMoveItem={handleMoveItem}
|
|
142
|
-
>
|
|
143
|
-
{indexes.map((index) => (
|
|
144
|
-
<Sortable.Item<HTMLDivElement> id={keys[index]} key={keys[index]}>
|
|
145
|
-
{({ relativeDropPosition, ...sortableProps }) => (
|
|
146
|
-
<ItemContainer {...sortableProps}>
|
|
147
|
-
{renderRow(index)}
|
|
148
|
-
{relativeDropPosition && (
|
|
149
|
-
<ListView.DragIndicator
|
|
150
|
-
$gap={0}
|
|
151
|
-
$colorScheme="primary"
|
|
152
|
-
$relativeDropPosition={relativeDropPosition}
|
|
153
|
-
$offsetLeft={0}
|
|
154
|
-
/>
|
|
155
|
-
)}
|
|
156
|
-
</ItemContainer>
|
|
157
|
-
)}
|
|
158
|
-
</Sortable.Item>
|
|
159
|
-
))}
|
|
160
|
-
</Sortable.Root>
|
|
161
|
-
) : (
|
|
162
|
-
indexes.map(renderRow)
|
|
163
|
-
)}
|
|
164
|
-
</Stack.V>
|
|
165
|
-
{expanded && renderExpandedContent?.()}
|
|
166
|
-
</InspectorPrimitives.Section>
|
|
167
|
-
);
|
|
168
|
-
});
|