@noya-app/noya-designsystem 0.1.23 → 0.1.25
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 +9 -9
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +12 -6
- package/dist/index.d.ts +12 -6
- package/dist/index.js +692 -603
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +357 -268
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Chip.tsx +14 -9
- package/src/components/ContextMenu.tsx +2 -1
- package/src/components/DropdownMenu.tsx +3 -2
- package/src/components/IconButton.tsx +2 -2
- package/src/components/Icons.tsx +18 -0
- package/src/components/InputField.tsx +34 -0
- package/src/components/ListView.tsx +33 -8
- package/src/components/SelectMenu.tsx +34 -4
- package/src/components/Switch.tsx +3 -0
- package/src/components/TreeView.tsx +3 -2
- package/src/components/internal/Menu.tsx +2 -1
package/package.json
CHANGED
package/src/components/Chip.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import { useDesignSystemTheme } from "../contexts/DesignSystemConfiguration";
|
|
|
5
5
|
import { useHover } from "../hooks/useHover";
|
|
6
6
|
|
|
7
7
|
type ChipColorScheme = "primary" | "secondary" | "error";
|
|
8
|
-
type ChipSize = "small" | "medium";
|
|
8
|
+
type ChipSize = "small" | "medium" | "large";
|
|
9
9
|
type ChipVariant = "solid" | "outlined" | "ghost";
|
|
10
10
|
|
|
11
11
|
const ChipElement = styled.span<{
|
|
@@ -49,15 +49,20 @@ const ChipElement = styled.span<{
|
|
|
49
49
|
// lineHeight: "1.4",
|
|
50
50
|
lineHeight: "15px",
|
|
51
51
|
whiteSpace: "pre",
|
|
52
|
-
...($size === "
|
|
52
|
+
...($size === "large"
|
|
53
53
|
? {
|
|
54
54
|
fontSize: "11px",
|
|
55
55
|
padding: "4px 8px",
|
|
56
56
|
}
|
|
57
|
-
:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
: $size === "medium"
|
|
58
|
+
? {
|
|
59
|
+
fontSize: "10px",
|
|
60
|
+
padding: "2px 6px",
|
|
61
|
+
}
|
|
62
|
+
: {
|
|
63
|
+
fontSize: "9px",
|
|
64
|
+
padding: "0px 4px",
|
|
65
|
+
}),
|
|
61
66
|
...($monospace && {
|
|
62
67
|
fontFamily: theme.fonts.monospace,
|
|
63
68
|
}),
|
|
@@ -96,7 +101,7 @@ const DeleteElement = styled(Cross1Icon)<{
|
|
|
96
101
|
cursor: "pointer",
|
|
97
102
|
opacity: 0.5,
|
|
98
103
|
|
|
99
|
-
...(size === "
|
|
104
|
+
...(size === "large"
|
|
100
105
|
? {
|
|
101
106
|
marginLeft: "2px",
|
|
102
107
|
// top: '-1px',
|
|
@@ -124,7 +129,7 @@ const AddElement = styled(PlusIcon).withConfig({
|
|
|
124
129
|
cursor: "pointer",
|
|
125
130
|
opacity: 0.5,
|
|
126
131
|
|
|
127
|
-
...(size === "
|
|
132
|
+
...(size === "large"
|
|
128
133
|
? {
|
|
129
134
|
marginRight: "2px",
|
|
130
135
|
top: "-1px",
|
|
@@ -168,7 +173,7 @@ export const Chip = memo(
|
|
|
168
173
|
addable,
|
|
169
174
|
clickable,
|
|
170
175
|
style,
|
|
171
|
-
size = "
|
|
176
|
+
size = "large",
|
|
172
177
|
variant = "solid",
|
|
173
178
|
monospace = false,
|
|
174
179
|
tabIndex,
|
|
@@ -3,6 +3,7 @@ import { useKeyboardShortcuts } from "@noya-app/noya-keymap";
|
|
|
3
3
|
import * as RadixContextMenu from "@radix-ui/react-context-menu";
|
|
4
4
|
import React, { ReactNode, memo, useCallback, useMemo } from "react";
|
|
5
5
|
import styled from "styled-components";
|
|
6
|
+
import { renderIcon } from "./Icons";
|
|
6
7
|
import { Spacer } from "./Spacer";
|
|
7
8
|
import {
|
|
8
9
|
CHECKBOX_RIGHT_INSET,
|
|
@@ -98,7 +99,7 @@ const ContextMenuItem = memo(function ContextMenuItem<T extends string>({
|
|
|
98
99
|
)}
|
|
99
100
|
{icon && (
|
|
100
101
|
<>
|
|
101
|
-
{icon}
|
|
102
|
+
{renderIcon(icon)}
|
|
102
103
|
<Spacer.Horizontal size={8} />
|
|
103
104
|
</>
|
|
104
105
|
)}
|
|
@@ -12,6 +12,7 @@ import React, {
|
|
|
12
12
|
} from "react";
|
|
13
13
|
import styled from "styled-components";
|
|
14
14
|
import { MenuItemProps, MenuProps } from "./ContextMenu";
|
|
15
|
+
import { renderIcon } from "./Icons";
|
|
15
16
|
import { Spacer } from "./Spacer";
|
|
16
17
|
import {
|
|
17
18
|
CHECKBOX_RIGHT_INSET,
|
|
@@ -73,7 +74,7 @@ const DropdownMenuItem = memo(function ContextMenuItem<T extends string>({
|
|
|
73
74
|
</StyledItemIndicator>
|
|
74
75
|
{icon && (
|
|
75
76
|
<>
|
|
76
|
-
{icon}
|
|
77
|
+
{renderIcon(icon)}
|
|
77
78
|
<Spacer.Horizontal size={8} />
|
|
78
79
|
</>
|
|
79
80
|
)}
|
|
@@ -89,7 +90,7 @@ const DropdownMenuItem = memo(function ContextMenuItem<T extends string>({
|
|
|
89
90
|
)}
|
|
90
91
|
{icon && (
|
|
91
92
|
<>
|
|
92
|
-
{icon}
|
|
93
|
+
{renderIcon(icon)}
|
|
93
94
|
<Spacer.Horizontal size={8} />
|
|
94
95
|
</>
|
|
95
96
|
)}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as Icons from "@noya-app/noya-icons";
|
|
2
1
|
import React, {
|
|
3
2
|
CSSProperties,
|
|
4
3
|
ForwardedRef,
|
|
@@ -8,9 +7,10 @@ import React, {
|
|
|
8
7
|
} from "react";
|
|
9
8
|
import { useTheme } from "styled-components";
|
|
10
9
|
import { Button, ButtonRootProps } from "./Button";
|
|
10
|
+
import { IconName, Icons } from "./Icons";
|
|
11
11
|
|
|
12
12
|
type Props = Omit<ButtonRootProps, "children" | "variant" | "flex" | "size"> & {
|
|
13
|
-
iconName:
|
|
13
|
+
iconName: IconName;
|
|
14
14
|
className?: string;
|
|
15
15
|
style?: CSSProperties;
|
|
16
16
|
selected?: boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as Icons from "@noya-app/noya-icons";
|
|
2
|
+
import React, { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
export type IconName = keyof typeof Icons;
|
|
5
|
+
|
|
6
|
+
export { Icons };
|
|
7
|
+
|
|
8
|
+
export function renderIcon(
|
|
9
|
+
iconName: Exclude<ReactNode, string> | IconName
|
|
10
|
+
): ReactNode {
|
|
11
|
+
if (typeof iconName === "string") {
|
|
12
|
+
const Icon = Icons[iconName as IconName];
|
|
13
|
+
|
|
14
|
+
return <Icon />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return iconName;
|
|
18
|
+
}
|
|
@@ -662,6 +662,39 @@ function InputFieldRoot({
|
|
|
662
662
|
);
|
|
663
663
|
}
|
|
664
664
|
|
|
665
|
+
const PrimitiveInputField = styled.input(({ theme, readOnly, disabled }) => {
|
|
666
|
+
return {
|
|
667
|
+
// placeholder
|
|
668
|
+
"&::placeholder": {
|
|
669
|
+
color: theme.colors.textDisabled,
|
|
670
|
+
},
|
|
671
|
+
...theme.textStyles.small,
|
|
672
|
+
color: readOnly
|
|
673
|
+
? theme.colors.textMuted
|
|
674
|
+
: disabled
|
|
675
|
+
? theme.colors.textDisabled
|
|
676
|
+
: theme.colors.text,
|
|
677
|
+
width: "0px", // Reset intrinsic width
|
|
678
|
+
flex: "1 1 0px",
|
|
679
|
+
position: "relative",
|
|
680
|
+
border: "0",
|
|
681
|
+
outline: "none",
|
|
682
|
+
minWidth: "0",
|
|
683
|
+
alignSelf: "stretch",
|
|
684
|
+
borderRadius: "4px",
|
|
685
|
+
paddingTop: "4px",
|
|
686
|
+
paddingBottom: "4px",
|
|
687
|
+
paddingLeft: "6px",
|
|
688
|
+
paddingRight: "6px",
|
|
689
|
+
background: theme.colors.inputBackground,
|
|
690
|
+
"&:focus": {
|
|
691
|
+
boxShadow: `0 0 0 2px ${theme.colors.primary}`,
|
|
692
|
+
},
|
|
693
|
+
userSelect: "all",
|
|
694
|
+
pointerEvents: "all",
|
|
695
|
+
};
|
|
696
|
+
});
|
|
697
|
+
|
|
665
698
|
export namespace InputField {
|
|
666
699
|
export const Root = memo(InputFieldRoot);
|
|
667
700
|
export const Input = memo(InputFieldInput);
|
|
@@ -670,4 +703,5 @@ export namespace InputField {
|
|
|
670
703
|
export const DropdownMenu = InputFieldDropdownMenu;
|
|
671
704
|
export const Button = InputFieldButton;
|
|
672
705
|
export const Label = InputFieldLabel;
|
|
706
|
+
export const PrimitiveElement = PrimitiveInputField;
|
|
673
707
|
}
|
|
@@ -66,14 +66,15 @@ type ListRowContextValue = {
|
|
|
66
66
|
// The dragged item isn't passed a context value (doing so causes an infinite loop),
|
|
67
67
|
// so we pass this separately. Rows need the indentation to look correct when dragging,
|
|
68
68
|
// and the dragged row doesn't have a ListRowContextValue.
|
|
69
|
-
type
|
|
69
|
+
type ListViewDraggingContextValue = {
|
|
70
70
|
indentation: number;
|
|
71
71
|
isDragging?: boolean;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
const
|
|
74
|
+
const ListViewDraggingContext = createContext<ListViewDraggingContextValue>({
|
|
75
75
|
indentation: 12,
|
|
76
76
|
});
|
|
77
|
+
(ListViewDraggingContext as any).displayName = "ListViewDraggingContext";
|
|
77
78
|
|
|
78
79
|
const ListRowContext = createContext<ListRowContextValue>({
|
|
79
80
|
marginType: "none",
|
|
@@ -88,6 +89,7 @@ const ListRowContext = createContext<ListRowContextValue>({
|
|
|
88
89
|
isSectionHeader: false,
|
|
89
90
|
colorScheme: "primary",
|
|
90
91
|
});
|
|
92
|
+
(ListRowContext as any).displayName = "ListRowContext";
|
|
91
93
|
|
|
92
94
|
/* ----------------------------------------------------------------------------
|
|
93
95
|
* RowTitle
|
|
@@ -386,7 +388,7 @@ const ListViewRow = forwardRef(function ListViewRow<
|
|
|
386
388
|
const { hoverProps } = useHover({
|
|
387
389
|
onHoverChange,
|
|
388
390
|
});
|
|
389
|
-
const { indentation, isDragging } = useContext(
|
|
391
|
+
const { indentation, isDragging } = useContext(ListViewDraggingContext);
|
|
390
392
|
|
|
391
393
|
const handlePress = useCallback(
|
|
392
394
|
(event: React.MouseEvent) => {
|
|
@@ -524,6 +526,7 @@ const ListViewRow = forwardRef(function ListViewRow<
|
|
|
524
526
|
const RenderItemContext = createContext<(index: number) => ReactNode>(
|
|
525
527
|
() => null
|
|
526
528
|
);
|
|
529
|
+
(RenderItemContext as any).displayName = "RenderItemContext";
|
|
527
530
|
|
|
528
531
|
const VirtualizedListRow = memo(function VirtualizedListRow({
|
|
529
532
|
index,
|
|
@@ -761,8 +764,29 @@ const ListViewRootInner = forwardRef(function ListViewRootInner<T>(
|
|
|
761
764
|
[data, renderItem]
|
|
762
765
|
);
|
|
763
766
|
|
|
767
|
+
// TODO: Do we still use section header properties anywhere?
|
|
768
|
+
const defaultContextValue = useMemo(
|
|
769
|
+
(): ListRowContextValue => ({
|
|
770
|
+
colorScheme,
|
|
771
|
+
marginType: "none",
|
|
772
|
+
selectedPosition: "only",
|
|
773
|
+
sortable,
|
|
774
|
+
expandable,
|
|
775
|
+
divider,
|
|
776
|
+
pressEventName,
|
|
777
|
+
variant,
|
|
778
|
+
gap,
|
|
779
|
+
sectionHeaderVariant: "normal",
|
|
780
|
+
isSectionHeader: false,
|
|
781
|
+
}),
|
|
782
|
+
[colorScheme, sortable, expandable, divider, pressEventName, variant, gap]
|
|
783
|
+
);
|
|
784
|
+
|
|
764
785
|
const getItemContextValue = useCallback(
|
|
765
786
|
(i: number): ListRowContextValue | undefined => {
|
|
787
|
+
if (variant === "bare" || variant === "normal")
|
|
788
|
+
return defaultContextValue;
|
|
789
|
+
|
|
766
790
|
const current = renderChild(i);
|
|
767
791
|
|
|
768
792
|
if (!isValidElement(current)) return;
|
|
@@ -827,6 +851,8 @@ const ListViewRootInner = forwardRef(function ListViewRootInner<T>(
|
|
|
827
851
|
};
|
|
828
852
|
},
|
|
829
853
|
[
|
|
854
|
+
variant,
|
|
855
|
+
defaultContextValue,
|
|
830
856
|
renderChild,
|
|
831
857
|
data.length,
|
|
832
858
|
colorScheme,
|
|
@@ -834,7 +860,6 @@ const ListViewRootInner = forwardRef(function ListViewRootInner<T>(
|
|
|
834
860
|
expandable,
|
|
835
861
|
divider,
|
|
836
862
|
pressEventName,
|
|
837
|
-
variant,
|
|
838
863
|
sectionHeaderVariant,
|
|
839
864
|
gap,
|
|
840
865
|
]
|
|
@@ -848,9 +873,9 @@ const ListViewRootInner = forwardRef(function ListViewRootInner<T>(
|
|
|
848
873
|
const renderOverlay = useCallback(
|
|
849
874
|
(index: number) => (
|
|
850
875
|
<div style={{ opacity: 0.25 }}>
|
|
851
|
-
<
|
|
876
|
+
<ListViewDraggingContext.Provider value={draggingContextOverlayValue}>
|
|
852
877
|
{renderItem(data[index], index, { isDragging: true })}
|
|
853
|
-
</
|
|
878
|
+
</ListViewDraggingContext.Provider>
|
|
854
879
|
</div>
|
|
855
880
|
),
|
|
856
881
|
[draggingContextOverlayValue, renderItem, data]
|
|
@@ -916,7 +941,7 @@ const ListViewRootInner = forwardRef(function ListViewRootInner<T>(
|
|
|
916
941
|
const draggingContextValue = useMemo(() => ({ indentation }), [indentation]);
|
|
917
942
|
|
|
918
943
|
return (
|
|
919
|
-
<
|
|
944
|
+
<ListViewDraggingContext.Provider value={draggingContextValue}>
|
|
920
945
|
<RootContainer
|
|
921
946
|
id={id}
|
|
922
947
|
className={className}
|
|
@@ -945,7 +970,7 @@ const ListViewRootInner = forwardRef(function ListViewRootInner<T>(
|
|
|
945
970
|
)
|
|
946
971
|
)}
|
|
947
972
|
</RootContainer>
|
|
948
|
-
</
|
|
973
|
+
</ListViewDraggingContext.Provider>
|
|
949
974
|
);
|
|
950
975
|
});
|
|
951
976
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DropdownChevronIcon } from "@noya-app/noya-icons";
|
|
2
2
|
import * as Select from "@radix-ui/react-select";
|
|
3
|
-
import React, { memo } from "react";
|
|
3
|
+
import React, { CSSProperties, memo } from "react";
|
|
4
4
|
import { styled } from "styled-components";
|
|
5
5
|
import { Button } from "./Button";
|
|
6
|
+
import { renderIcon } from "./Icons";
|
|
6
7
|
import { Spacer } from "./Spacer";
|
|
7
8
|
import { MenuItem, RegularMenuItem, styles } from "./internal/Menu";
|
|
8
9
|
|
|
@@ -14,6 +15,13 @@ type Props<T extends string> = {
|
|
|
14
15
|
value: T;
|
|
15
16
|
onSelect?: (value: T) => void;
|
|
16
17
|
placeholder?: string;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
readOnly?: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const readOnlyStyle: CSSProperties = {
|
|
23
|
+
justifyContent: "flex-start",
|
|
24
|
+
textAlign: "left",
|
|
17
25
|
};
|
|
18
26
|
|
|
19
27
|
export const SelectMenu = memo(function SelectMenu<T extends string = string>({
|
|
@@ -24,6 +32,8 @@ export const SelectMenu = memo(function SelectMenu<T extends string = string>({
|
|
|
24
32
|
value,
|
|
25
33
|
onSelect,
|
|
26
34
|
placeholder,
|
|
35
|
+
disabled,
|
|
36
|
+
readOnly,
|
|
27
37
|
}: Props<T>) {
|
|
28
38
|
const selectedItem = menuItems.find(
|
|
29
39
|
(item): item is RegularMenuItem<T> =>
|
|
@@ -31,13 +41,33 @@ export const SelectMenu = memo(function SelectMenu<T extends string = string>({
|
|
|
31
41
|
);
|
|
32
42
|
const icon = selectedItem?.icon;
|
|
33
43
|
|
|
44
|
+
if (readOnly) {
|
|
45
|
+
return (
|
|
46
|
+
<Button
|
|
47
|
+
id={id}
|
|
48
|
+
style={style}
|
|
49
|
+
contentStyle={readOnlyStyle}
|
|
50
|
+
className={className}
|
|
51
|
+
disabled={disabled}
|
|
52
|
+
>
|
|
53
|
+
{icon && (
|
|
54
|
+
<>
|
|
55
|
+
{renderIcon(icon)}
|
|
56
|
+
<Spacer.Horizontal size={8} />
|
|
57
|
+
</>
|
|
58
|
+
)}
|
|
59
|
+
{selectedItem?.title ?? value}
|
|
60
|
+
</Button>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
34
64
|
return (
|
|
35
65
|
<Select.Root value={value} onValueChange={onSelect}>
|
|
36
66
|
<Select.SelectTrigger asChild>
|
|
37
|
-
<Button id={id} style={style} className={className}>
|
|
67
|
+
<Button id={id} style={style} className={className} disabled={disabled}>
|
|
38
68
|
{icon && (
|
|
39
69
|
<>
|
|
40
|
-
{icon}
|
|
70
|
+
{renderIcon(icon)}
|
|
41
71
|
<Spacer.Horizontal size={8} />
|
|
42
72
|
</>
|
|
43
73
|
)}
|
|
@@ -86,7 +116,7 @@ const SelectItem = React.forwardRef(
|
|
|
86
116
|
<StyledItem {...props} ref={forwardedRef}>
|
|
87
117
|
{icon && (
|
|
88
118
|
<>
|
|
89
|
-
{icon}
|
|
119
|
+
{renderIcon(icon)}
|
|
90
120
|
<Spacer.Horizontal size={8} />
|
|
91
121
|
</>
|
|
92
122
|
)}
|
|
@@ -45,17 +45,20 @@ interface Props {
|
|
|
45
45
|
value: boolean;
|
|
46
46
|
onChange: (value: boolean) => void;
|
|
47
47
|
colorScheme?: SwitchColorScheme;
|
|
48
|
+
disabled?: boolean;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
export const Switch = function Switch({
|
|
51
52
|
value,
|
|
52
53
|
onChange,
|
|
53
54
|
colorScheme = "normal",
|
|
55
|
+
disabled,
|
|
54
56
|
}: Props) {
|
|
55
57
|
return (
|
|
56
58
|
<SwitchRoot
|
|
57
59
|
$colorScheme={colorScheme}
|
|
58
60
|
checked={value}
|
|
61
|
+
disabled={disabled}
|
|
59
62
|
onCheckedChange={(newValue) => {
|
|
60
63
|
onChange(newValue);
|
|
61
64
|
}}
|
|
@@ -7,6 +7,7 @@ import React, {
|
|
|
7
7
|
useContext,
|
|
8
8
|
} from "react";
|
|
9
9
|
import { IconButton } from "./IconButton";
|
|
10
|
+
import { IconName, renderIcon } from "./Icons";
|
|
10
11
|
import { ListView } from "./ListView";
|
|
11
12
|
import { Spacer } from "./Spacer";
|
|
12
13
|
|
|
@@ -15,7 +16,7 @@ import { Spacer } from "./Spacer";
|
|
|
15
16
|
* ------------------------------------------------------------------------- */
|
|
16
17
|
|
|
17
18
|
type TreeRowBaseProps = {
|
|
18
|
-
icon?: ReactNode;
|
|
19
|
+
icon?: Exclude<ReactNode, string> | IconName;
|
|
19
20
|
expanded?: boolean;
|
|
20
21
|
onClickChevron?: ({ altKey }: { altKey: boolean }) => void;
|
|
21
22
|
};
|
|
@@ -61,7 +62,7 @@ const TreeRow = forwardRef(function TreeRow<MenuItemType extends string>(
|
|
|
61
62
|
)}
|
|
62
63
|
{icon && (
|
|
63
64
|
<>
|
|
64
|
-
{icon}
|
|
65
|
+
{renderIcon(icon)}
|
|
65
66
|
<Spacer.Horizontal size={10} />
|
|
66
67
|
</>
|
|
67
68
|
)}
|
|
@@ -4,6 +4,7 @@ import styled, { CSSObject } from "styled-components";
|
|
|
4
4
|
import { useDesignSystemConfiguration } from "../../contexts/DesignSystemConfiguration";
|
|
5
5
|
import { Theme } from "../../theme";
|
|
6
6
|
import withSeparatorElements from "../../utils/withSeparatorElements";
|
|
7
|
+
import { IconName } from "../Icons";
|
|
7
8
|
|
|
8
9
|
export const SEPARATOR_ITEM = "separator";
|
|
9
10
|
|
|
@@ -63,7 +64,7 @@ export type RegularMenuItem<T extends string> = {
|
|
|
63
64
|
shortcut?: string;
|
|
64
65
|
checked?: boolean;
|
|
65
66
|
disabled?: boolean;
|
|
66
|
-
icon?: ReactNode;
|
|
67
|
+
icon?: Exclude<ReactNode, string> | IconName;
|
|
67
68
|
items?: MenuItem<T>[];
|
|
68
69
|
role?: MenuItemRole;
|
|
69
70
|
};
|