@munchi_oy/native-ui 0.1.0
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/dist/index.d.mts +568 -0
- package/dist/index.d.ts +568 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/global.css +53 -0
- package/nativewind-env.d.ts +2 -0
- package/package.json +88 -0
- package/src/MAlert.tsx +38 -0
- package/src/MAnimation.tsx +55 -0
- package/src/MAvatar.tsx +111 -0
- package/src/MBadge.tsx +72 -0
- package/src/MButton.tsx +90 -0
- package/src/MCard.tsx +15 -0
- package/src/MChevron.tsx +47 -0
- package/src/MConfirmation.tsx +68 -0
- package/src/MCountDown.tsx +120 -0
- package/src/MDateTimePicker.tsx +124 -0
- package/src/MDivider.tsx +69 -0
- package/src/MDrawerRightPanel.tsx +187 -0
- package/src/MDropdown.tsx +277 -0
- package/src/MInput.tsx +162 -0
- package/src/MLabel.tsx +3 -0
- package/src/MLucideIcon.tsx +21 -0
- package/src/MModal.tsx +287 -0
- package/src/MNativeAlert.tsx +33 -0
- package/src/MNumpad.tsx +520 -0
- package/src/MPicker.tsx +150 -0
- package/src/MPinPadKeys.tsx +104 -0
- package/src/MPortal.tsx +4 -0
- package/src/MProgressBar.tsx +74 -0
- package/src/MRadioGroup.tsx +4 -0
- package/src/MRequiredLabel.tsx +21 -0
- package/src/MResponsiveContainer.tsx +74 -0
- package/src/MSearch.tsx +138 -0
- package/src/MSelector.tsx +48 -0
- package/src/MSkeleton.tsx +3 -0
- package/src/MSwitch.tsx +13 -0
- package/src/MTable.tsx +17 -0
- package/src/MTabs.tsx +198 -0
- package/src/MText.tsx +51 -0
- package/src/MTimerUp.tsx +88 -0
- package/src/MToggle.tsx +51 -0
- package/src/constants.ts +19 -0
- package/src/hooks/useColorScheme.tsx +12 -0
- package/src/hooks/useIconColors.ts +19 -0
- package/src/index.ts +124 -0
- package/src/primitives/accordion.tsx +143 -0
- package/src/primitives/alert-dialog.tsx +181 -0
- package/src/primitives/alert.tsx +94 -0
- package/src/primitives/aspect-ratio.tsx +5 -0
- package/src/primitives/avatar.tsx +47 -0
- package/src/primitives/badge.tsx +57 -0
- package/src/primitives/button.tsx +92 -0
- package/src/primitives/card.tsx +86 -0
- package/src/primitives/checkbox.tsx +35 -0
- package/src/primitives/collapsible.tsx +9 -0
- package/src/primitives/context-menu.tsx +255 -0
- package/src/primitives/dialog.tsx +166 -0
- package/src/primitives/dropdown-menu.tsx +264 -0
- package/src/primitives/hover-card.tsx +45 -0
- package/src/primitives/input.tsx +25 -0
- package/src/primitives/label.tsx +33 -0
- package/src/primitives/menubar.tsx +266 -0
- package/src/primitives/navigation-menu.tsx +192 -0
- package/src/primitives/popover.tsx +46 -0
- package/src/primitives/progress.tsx +82 -0
- package/src/primitives/radio-group.tsx +42 -0
- package/src/primitives/select.tsx +192 -0
- package/src/primitives/separator.tsx +28 -0
- package/src/primitives/skeleton.tsx +39 -0
- package/src/primitives/switch.tsx +102 -0
- package/src/primitives/table.tsx +107 -0
- package/src/primitives/tabs.tsx +66 -0
- package/src/primitives/text.tsx +28 -0
- package/src/primitives/textarea.tsx +39 -0
- package/src/primitives/toggle-group.tsx +89 -0
- package/src/primitives/toggle.tsx +91 -0
- package/src/primitives/tooltip.tsx +40 -0
- package/src/primitives/typography.tsx +214 -0
- package/src/theme.ts +43 -0
- package/src/tokens.ts +7 -0
- package/src/utils.ts +14 -0
- package/tailwind.config.ts +112 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type VariantProps, cva } from "class-variance-authority";
|
|
2
|
+
import type { LucideIcon } from "lucide-react-native";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { View, type ViewProps } from "react-native";
|
|
5
|
+
import { cn } from "../utils";
|
|
6
|
+
import { Text } from "./text";
|
|
7
|
+
|
|
8
|
+
const alertVariants = cva(
|
|
9
|
+
"relative bg-background w-full rounded-lg border border-border p-4 shadow shadow-foreground/10",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: "",
|
|
14
|
+
destructive: "border-destructive"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: "default"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const ICON_COLORS = {
|
|
24
|
+
default: "hsl(240 10% 3.9%)",
|
|
25
|
+
destructive: "hsl(0 84.2% 60.2%)"
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
const Alert = React.forwardRef<
|
|
29
|
+
React.ElementRef<typeof View>,
|
|
30
|
+
ViewProps &
|
|
31
|
+
VariantProps<typeof alertVariants> & {
|
|
32
|
+
icon: LucideIcon;
|
|
33
|
+
iconSize?: number;
|
|
34
|
+
iconClassName?: ViewProps["className"];
|
|
35
|
+
}
|
|
36
|
+
>(
|
|
37
|
+
(
|
|
38
|
+
{
|
|
39
|
+
className,
|
|
40
|
+
variant,
|
|
41
|
+
children,
|
|
42
|
+
icon: Icon,
|
|
43
|
+
iconSize = 16,
|
|
44
|
+
iconClassName,
|
|
45
|
+
...props
|
|
46
|
+
},
|
|
47
|
+
ref
|
|
48
|
+
) => {
|
|
49
|
+
const iconColor = ICON_COLORS[variant ?? "default"];
|
|
50
|
+
return (
|
|
51
|
+
<View
|
|
52
|
+
ref={ref}
|
|
53
|
+
role="alert"
|
|
54
|
+
className={alertVariants({ variant, className })}
|
|
55
|
+
{...props}
|
|
56
|
+
>
|
|
57
|
+
<View className="absolute left-3.5 top-4 -translate-y-0.5">
|
|
58
|
+
<Icon size={iconSize} color={iconColor} />
|
|
59
|
+
</View>
|
|
60
|
+
{children}
|
|
61
|
+
</View>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
Alert.displayName = "Alert";
|
|
66
|
+
|
|
67
|
+
const AlertTitle = React.forwardRef<
|
|
68
|
+
React.ElementRef<typeof Text>,
|
|
69
|
+
React.ComponentPropsWithoutRef<typeof Text>
|
|
70
|
+
>(({ className, ...props }, ref) => (
|
|
71
|
+
<Text
|
|
72
|
+
ref={ref}
|
|
73
|
+
className={cn(
|
|
74
|
+
"pl-7 mb-1 font-medium text-base leading-none tracking-tight text-foreground",
|
|
75
|
+
className
|
|
76
|
+
)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
));
|
|
80
|
+
AlertTitle.displayName = "AlertTitle";
|
|
81
|
+
|
|
82
|
+
const AlertDescription = React.forwardRef<
|
|
83
|
+
React.ElementRef<typeof Text>,
|
|
84
|
+
React.ComponentPropsWithoutRef<typeof Text>
|
|
85
|
+
>(({ className, ...props }, ref) => (
|
|
86
|
+
<Text
|
|
87
|
+
ref={ref}
|
|
88
|
+
className={cn("pl-7 text-sm leading-relaxed text-foreground", className)}
|
|
89
|
+
{...props}
|
|
90
|
+
/>
|
|
91
|
+
));
|
|
92
|
+
AlertDescription.displayName = "AlertDescription";
|
|
93
|
+
|
|
94
|
+
export { Alert, AlertDescription, AlertTitle };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as AvatarPrimitive from "@rn-primitives/avatar";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../utils";
|
|
4
|
+
|
|
5
|
+
const Avatar = React.forwardRef<
|
|
6
|
+
AvatarPrimitive.RootRef,
|
|
7
|
+
AvatarPrimitive.RootProps
|
|
8
|
+
>(({ className, ...props }, ref) => (
|
|
9
|
+
<AvatarPrimitive.Root
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
));
|
|
18
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
19
|
+
|
|
20
|
+
const AvatarImage = React.forwardRef<
|
|
21
|
+
AvatarPrimitive.ImageRef,
|
|
22
|
+
AvatarPrimitive.ImageProps
|
|
23
|
+
>(({ className, ...props }, ref) => (
|
|
24
|
+
<AvatarPrimitive.Image
|
|
25
|
+
ref={ref}
|
|
26
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
));
|
|
30
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
31
|
+
|
|
32
|
+
const AvatarFallback = React.forwardRef<
|
|
33
|
+
AvatarPrimitive.FallbackRef,
|
|
34
|
+
AvatarPrimitive.FallbackProps
|
|
35
|
+
>(({ className, ...props }, ref) => (
|
|
36
|
+
<AvatarPrimitive.Fallback
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={cn(
|
|
39
|
+
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
|
40
|
+
className
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
));
|
|
45
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
46
|
+
|
|
47
|
+
export { Avatar, AvatarFallback, AvatarImage };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as Slot from "@rn-primitives/slot";
|
|
2
|
+
import type { SlottableViewProps } from "@rn-primitives/types";
|
|
3
|
+
import { type VariantProps, cva } from "class-variance-authority";
|
|
4
|
+
import { View } from "react-native";
|
|
5
|
+
import { cn } from "../utils";
|
|
6
|
+
import { TextClassContext } from "./text";
|
|
7
|
+
|
|
8
|
+
const badgeVariants = cva(
|
|
9
|
+
"web:inline-flex items-center rounded-full border border-border px-2.5 py-0.5 web:transition-colors web:focus:outline-none web:focus:ring-2 web:focus:ring-ring web:focus:ring-offset-2",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default:
|
|
14
|
+
"border-transparent bg-primary web:hover:opacity-80 active:opacity-80",
|
|
15
|
+
secondary:
|
|
16
|
+
"border-transparent bg-secondary web:hover:opacity-80 active:opacity-80",
|
|
17
|
+
destructive:
|
|
18
|
+
"border-transparent bg-destructive web:hover:opacity-80 active:opacity-80",
|
|
19
|
+
outline: "text-foreground"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: "default"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const badgeTextVariants = cva("text-xs font-semibold ", {
|
|
29
|
+
variants: {
|
|
30
|
+
variant: {
|
|
31
|
+
default: "text-primary-foreground",
|
|
32
|
+
secondary: "text-secondary-foreground",
|
|
33
|
+
destructive: "text-destructive-foreground",
|
|
34
|
+
outline: "text-foreground"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
defaultVariants: {
|
|
38
|
+
variant: "default"
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
type BadgeProps = SlottableViewProps & VariantProps<typeof badgeVariants>;
|
|
43
|
+
|
|
44
|
+
function Badge({ className, variant, asChild, ...props }: BadgeProps) {
|
|
45
|
+
const Component = asChild ? Slot.View : View;
|
|
46
|
+
return (
|
|
47
|
+
<TextClassContext.Provider value={badgeTextVariants({ variant })}>
|
|
48
|
+
<Component
|
|
49
|
+
className={cn(badgeVariants({ variant }), className)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
</TextClassContext.Provider>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { Badge, badgeTextVariants, badgeVariants };
|
|
57
|
+
export type { BadgeProps };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { type VariantProps, cva } from "class-variance-authority";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Pressable } from "react-native";
|
|
4
|
+
import { cn } from "../utils";
|
|
5
|
+
import { TextClassContext } from "./text";
|
|
6
|
+
|
|
7
|
+
const buttonVariants = cva(
|
|
8
|
+
"group flex items-center justify-center rounded-md web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "bg-primary web:hover:opacity-90 active:opacity-90",
|
|
13
|
+
destructive: "bg-destructive web:hover:opacity-90 active:opacity-90",
|
|
14
|
+
outline:
|
|
15
|
+
"border border-input bg-background web:hover:bg-accent web:hover:text-accent-foreground active:bg-accent",
|
|
16
|
+
secondary: "bg-secondary web:hover:opacity-80 active:opacity-80",
|
|
17
|
+
ghost:
|
|
18
|
+
"web:hover:bg-accent web:hover:text-accent-foreground active:bg-accent",
|
|
19
|
+
link: "web:underline-offset-4 web:hover:underline web:focus:underline"
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
default: "h-10 px-4 py-2 native:h-12 native:px-5 native:py-3",
|
|
23
|
+
sm: "h-9 rounded-md px-3",
|
|
24
|
+
lg: "h-11 rounded-md px-8 native:h-14",
|
|
25
|
+
icon: "h-10 w-10"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
variant: "default",
|
|
30
|
+
size: "default"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const buttonTextVariants = cva(
|
|
36
|
+
"web:whitespace-nowrap text-sm native:text-base font-medium text-foreground web:transition-colors",
|
|
37
|
+
{
|
|
38
|
+
variants: {
|
|
39
|
+
variant: {
|
|
40
|
+
default: "text-primary-foreground",
|
|
41
|
+
destructive: "text-destructive-foreground",
|
|
42
|
+
outline: "group-active:text-accent-foreground",
|
|
43
|
+
secondary:
|
|
44
|
+
"text-secondary-foreground group-active:text-secondary-foreground",
|
|
45
|
+
ghost: "group-active:text-accent-foreground",
|
|
46
|
+
link: "text-primary group-active:underline"
|
|
47
|
+
},
|
|
48
|
+
size: {
|
|
49
|
+
default: "",
|
|
50
|
+
sm: "",
|
|
51
|
+
lg: "native:text-lg",
|
|
52
|
+
icon: ""
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
defaultVariants: {
|
|
56
|
+
variant: "default",
|
|
57
|
+
size: "default"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
type ButtonProps = React.ComponentPropsWithoutRef<typeof Pressable> &
|
|
63
|
+
VariantProps<typeof buttonVariants>;
|
|
64
|
+
|
|
65
|
+
const Button = React.forwardRef<
|
|
66
|
+
React.ElementRef<typeof Pressable>,
|
|
67
|
+
ButtonProps
|
|
68
|
+
>(({ className, variant, size, ...props }, ref) => {
|
|
69
|
+
return (
|
|
70
|
+
<TextClassContext.Provider
|
|
71
|
+
value={buttonTextVariants({
|
|
72
|
+
variant,
|
|
73
|
+
size,
|
|
74
|
+
className: "web:pointer-events-none"
|
|
75
|
+
})}
|
|
76
|
+
>
|
|
77
|
+
<Pressable
|
|
78
|
+
className={cn(
|
|
79
|
+
props.disabled && "opacity-50 web:pointer-events-none",
|
|
80
|
+
buttonVariants({ variant, size, className })
|
|
81
|
+
)}
|
|
82
|
+
ref={ref}
|
|
83
|
+
role="button"
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
</TextClassContext.Provider>
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
Button.displayName = "Button";
|
|
90
|
+
|
|
91
|
+
export { Button, buttonTextVariants, buttonVariants };
|
|
92
|
+
export type { ButtonProps };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { TextRef, ViewRef } from "@rn-primitives/types";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Text, type TextProps, View, type ViewProps } from "react-native";
|
|
4
|
+
import { cn } from "../utils";
|
|
5
|
+
import { TextClassContext } from "./text";
|
|
6
|
+
|
|
7
|
+
const Card = React.forwardRef<ViewRef, ViewProps>(
|
|
8
|
+
({ className, ...props }, ref) => (
|
|
9
|
+
<View
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
"rounded-lg border border-border bg-card shadow-sm shadow-foreground/10",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
18
|
+
);
|
|
19
|
+
Card.displayName = "Card";
|
|
20
|
+
|
|
21
|
+
const CardHeader = React.forwardRef<ViewRef, ViewProps>(
|
|
22
|
+
({ className, ...props }, ref) => (
|
|
23
|
+
<View
|
|
24
|
+
ref={ref}
|
|
25
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
CardHeader.displayName = "CardHeader";
|
|
31
|
+
|
|
32
|
+
const CardTitle = React.forwardRef<TextRef, TextProps>(
|
|
33
|
+
({ className, ...props }, ref) => (
|
|
34
|
+
<Text
|
|
35
|
+
role="heading"
|
|
36
|
+
aria-level={3}
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={cn(
|
|
39
|
+
"text-2xl text-card-foreground font-semibold leading-none tracking-tight",
|
|
40
|
+
className
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
CardTitle.displayName = "CardTitle";
|
|
47
|
+
|
|
48
|
+
const CardDescription = React.forwardRef<TextRef, TextProps>(
|
|
49
|
+
({ className, ...props }, ref) => (
|
|
50
|
+
<Text
|
|
51
|
+
ref={ref}
|
|
52
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
CardDescription.displayName = "CardDescription";
|
|
58
|
+
|
|
59
|
+
const CardContent = React.forwardRef<ViewRef, ViewProps>(
|
|
60
|
+
({ className, ...props }, ref) => (
|
|
61
|
+
<TextClassContext.Provider value="text-card-foreground">
|
|
62
|
+
<View ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
63
|
+
</TextClassContext.Provider>
|
|
64
|
+
)
|
|
65
|
+
);
|
|
66
|
+
CardContent.displayName = "CardContent";
|
|
67
|
+
|
|
68
|
+
const CardFooter = React.forwardRef<ViewRef, ViewProps>(
|
|
69
|
+
({ className, ...props }, ref) => (
|
|
70
|
+
<View
|
|
71
|
+
ref={ref}
|
|
72
|
+
className={cn("flex flex-row items-center p-6 pt-0", className)}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
CardFooter.displayName = "CardFooter";
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
Card,
|
|
81
|
+
CardContent,
|
|
82
|
+
CardDescription,
|
|
83
|
+
CardFooter,
|
|
84
|
+
CardHeader,
|
|
85
|
+
CardTitle
|
|
86
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as CheckboxPrimitive from "@rn-primitives/checkbox";
|
|
2
|
+
import { Check } from "lucide-react-native";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Platform } from "react-native";
|
|
5
|
+
import { cn } from "../utils";
|
|
6
|
+
|
|
7
|
+
const Checkbox = React.forwardRef<
|
|
8
|
+
CheckboxPrimitive.RootRef,
|
|
9
|
+
CheckboxPrimitive.RootProps
|
|
10
|
+
>(({ className, ...props }, ref) => {
|
|
11
|
+
return (
|
|
12
|
+
<CheckboxPrimitive.Root
|
|
13
|
+
ref={ref}
|
|
14
|
+
className={cn(
|
|
15
|
+
"web:peer h-4 w-4 native:h-[20] native:w-[20] shrink-0 rounded-sm native:rounded border border-primary web:ring-offset-background web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
16
|
+
props.checked && "bg-primary",
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
<CheckboxPrimitive.Indicator
|
|
22
|
+
className={cn("items-center justify-center h-full w-full")}
|
|
23
|
+
>
|
|
24
|
+
<Check
|
|
25
|
+
size={12}
|
|
26
|
+
strokeWidth={Platform.OS === "web" ? 2.5 : 3.5}
|
|
27
|
+
className="text-primary-foreground"
|
|
28
|
+
/>
|
|
29
|
+
</CheckboxPrimitive.Indicator>
|
|
30
|
+
</CheckboxPrimitive.Root>
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
34
|
+
|
|
35
|
+
export { Checkbox };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as CollapsiblePrimitive from "@rn-primitives/collapsible";
|
|
2
|
+
|
|
3
|
+
const Collapsible = CollapsiblePrimitive.Root;
|
|
4
|
+
|
|
5
|
+
const CollapsibleTrigger = CollapsiblePrimitive.Trigger;
|
|
6
|
+
|
|
7
|
+
const CollapsibleContent = CollapsiblePrimitive.Content;
|
|
8
|
+
|
|
9
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import * as ContextMenuPrimitive from "@rn-primitives/context-menu";
|
|
2
|
+
import {
|
|
3
|
+
Check,
|
|
4
|
+
ChevronDown,
|
|
5
|
+
ChevronRight,
|
|
6
|
+
ChevronUp
|
|
7
|
+
} from "lucide-react-native";
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import {
|
|
10
|
+
Platform,
|
|
11
|
+
type StyleProp,
|
|
12
|
+
StyleSheet,
|
|
13
|
+
Text,
|
|
14
|
+
type TextProps,
|
|
15
|
+
View,
|
|
16
|
+
type ViewProps,
|
|
17
|
+
type ViewStyle
|
|
18
|
+
} from "react-native";
|
|
19
|
+
import { cn } from "../utils";
|
|
20
|
+
import { TextClassContext } from "./text";
|
|
21
|
+
|
|
22
|
+
const ContextMenu = ContextMenuPrimitive.Root;
|
|
23
|
+
const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
24
|
+
const ContextMenuGroup = ContextMenuPrimitive.Group;
|
|
25
|
+
const ContextMenuSub = ContextMenuPrimitive.Sub;
|
|
26
|
+
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
|
27
|
+
|
|
28
|
+
const ContextMenuSubTrigger = React.forwardRef<
|
|
29
|
+
ContextMenuPrimitive.SubTriggerRef,
|
|
30
|
+
ContextMenuPrimitive.SubTriggerProps & {
|
|
31
|
+
inset?: boolean;
|
|
32
|
+
}
|
|
33
|
+
>(({ className, inset, children, ...props }, ref) => {
|
|
34
|
+
const { open } = ContextMenuPrimitive.useSubContext();
|
|
35
|
+
const Icon =
|
|
36
|
+
Platform.OS === "web" ? ChevronRight : open ? ChevronUp : ChevronDown;
|
|
37
|
+
return (
|
|
38
|
+
<TextClassContext.Provider
|
|
39
|
+
value={cn(
|
|
40
|
+
"select-none text-sm native:text-lg text-primary",
|
|
41
|
+
open && "native:text-accent-foreground"
|
|
42
|
+
)}
|
|
43
|
+
>
|
|
44
|
+
<ContextMenuPrimitive.SubTrigger
|
|
45
|
+
ref={ref}
|
|
46
|
+
className={cn(
|
|
47
|
+
"flex flex-row web:cursor-default web:select-none items-center gap-2 web:focus:bg-accent active:bg-accent web:hover:bg-accent rounded-sm px-2 py-1.5 native:py-2 web:outline-none",
|
|
48
|
+
open && "bg-accent",
|
|
49
|
+
inset && "pl-8",
|
|
50
|
+
className
|
|
51
|
+
)}
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
54
|
+
<>{children}</>
|
|
55
|
+
<Icon size={18} className="ml-auto text-foreground" />
|
|
56
|
+
</ContextMenuPrimitive.SubTrigger>
|
|
57
|
+
</TextClassContext.Provider>
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
|
|
61
|
+
|
|
62
|
+
const ContextMenuSubContent = React.forwardRef<
|
|
63
|
+
ContextMenuPrimitive.SubContentRef,
|
|
64
|
+
ContextMenuPrimitive.SubContentProps
|
|
65
|
+
>(({ className, ...props }, ref) => {
|
|
66
|
+
const { open } = ContextMenuPrimitive.useSubContext();
|
|
67
|
+
return (
|
|
68
|
+
<ContextMenuPrimitive.SubContent
|
|
69
|
+
ref={ref}
|
|
70
|
+
className={cn(
|
|
71
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border mt-1 border-border bg-popover p-1 shadow-md shadow-foreground/5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
72
|
+
open
|
|
73
|
+
? "web:animate-in web:fade-in-0 web:zoom-in-95"
|
|
74
|
+
: "web:animate-out web:fade-out-0 web:zoom-out",
|
|
75
|
+
className
|
|
76
|
+
)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
ContextMenuSubContent.displayName = "ContextMenuSubContent";
|
|
82
|
+
|
|
83
|
+
const ContextMenuContent = React.forwardRef<
|
|
84
|
+
ContextMenuPrimitive.ContentRef,
|
|
85
|
+
ContextMenuPrimitive.ContentProps & {
|
|
86
|
+
overlayStyle?: StyleProp<ViewStyle>;
|
|
87
|
+
overlayClassName?: ViewProps["className"];
|
|
88
|
+
portalHost?: string;
|
|
89
|
+
}
|
|
90
|
+
>(
|
|
91
|
+
(
|
|
92
|
+
{ className, overlayClassName, overlayStyle, portalHost, ...props },
|
|
93
|
+
ref
|
|
94
|
+
) => {
|
|
95
|
+
const { open } = ContextMenuPrimitive.useRootContext();
|
|
96
|
+
return (
|
|
97
|
+
<ContextMenuPrimitive.Portal hostName={portalHost}>
|
|
98
|
+
<ContextMenuPrimitive.Overlay
|
|
99
|
+
style={
|
|
100
|
+
overlayStyle
|
|
101
|
+
? StyleSheet.flatten([
|
|
102
|
+
Platform.OS !== "web" ? StyleSheet.absoluteFill : undefined,
|
|
103
|
+
overlayStyle
|
|
104
|
+
])
|
|
105
|
+
: Platform.OS !== "web"
|
|
106
|
+
? StyleSheet.absoluteFill
|
|
107
|
+
: undefined
|
|
108
|
+
}
|
|
109
|
+
className={overlayClassName}
|
|
110
|
+
>
|
|
111
|
+
<ContextMenuPrimitive.Content
|
|
112
|
+
ref={ref}
|
|
113
|
+
className={cn(
|
|
114
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 shadow-md shadow-foreground/5 web:data-[side=bottom]:slide-in-from-top-2 web:data-[side=left]:slide-in-from-right-2 web:data-[side=right]:slide-in-from-left-2 web:data-[side=top]:slide-in-from-bottom-2",
|
|
115
|
+
open
|
|
116
|
+
? "web:animate-in web:fade-in-0 web:zoom-in-95"
|
|
117
|
+
: "web:animate-out web:fade-out-0 web:zoom-out-95",
|
|
118
|
+
className
|
|
119
|
+
)}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
</ContextMenuPrimitive.Overlay>
|
|
123
|
+
</ContextMenuPrimitive.Portal>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
|
|
128
|
+
|
|
129
|
+
const ContextMenuItem = React.forwardRef<
|
|
130
|
+
ContextMenuPrimitive.ItemRef,
|
|
131
|
+
ContextMenuPrimitive.ItemProps & {
|
|
132
|
+
inset?: boolean;
|
|
133
|
+
}
|
|
134
|
+
>(({ className, inset, ...props }, ref) => (
|
|
135
|
+
<TextClassContext.Provider value="select-none text-sm native:text-lg text-popover-foreground web:group-focus:text-accent-foreground">
|
|
136
|
+
<ContextMenuPrimitive.Item
|
|
137
|
+
ref={ref}
|
|
138
|
+
className={cn(
|
|
139
|
+
"relative flex flex-row web:cursor-default items-center gap-2 rounded-sm px-2 py-1.5 native:py-2 web:outline-none web:focus:bg-accent active:bg-accent web:hover:bg-accent group",
|
|
140
|
+
inset && "pl-8",
|
|
141
|
+
props.disabled && "opacity-50 web:pointer-events-none",
|
|
142
|
+
className
|
|
143
|
+
)}
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
</TextClassContext.Provider>
|
|
147
|
+
));
|
|
148
|
+
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
|
|
149
|
+
|
|
150
|
+
const ContextMenuCheckboxItem = React.forwardRef<
|
|
151
|
+
ContextMenuPrimitive.CheckboxItemRef,
|
|
152
|
+
ContextMenuPrimitive.CheckboxItemProps
|
|
153
|
+
>(({ className, children, ...props }, ref) => (
|
|
154
|
+
<ContextMenuPrimitive.CheckboxItem
|
|
155
|
+
ref={ref}
|
|
156
|
+
className={cn(
|
|
157
|
+
"relative flex flex-row web:cursor-default items-center web:group rounded-sm py-1.5 native:py-2 pl-8 pr-2 web:outline-none web:focus:bg-accent active:bg-accent",
|
|
158
|
+
props.disabled && "web:pointer-events-none opacity-50",
|
|
159
|
+
className
|
|
160
|
+
)}
|
|
161
|
+
{...props}
|
|
162
|
+
>
|
|
163
|
+
<View className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
164
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
165
|
+
<Check size={14} strokeWidth={3} className="text-foreground" />
|
|
166
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
167
|
+
</View>
|
|
168
|
+
<>{children}</>
|
|
169
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
170
|
+
));
|
|
171
|
+
ContextMenuCheckboxItem.displayName =
|
|
172
|
+
ContextMenuPrimitive.CheckboxItem.displayName;
|
|
173
|
+
|
|
174
|
+
const ContextMenuRadioItem = React.forwardRef<
|
|
175
|
+
ContextMenuPrimitive.RadioItemRef,
|
|
176
|
+
ContextMenuPrimitive.RadioItemProps
|
|
177
|
+
>(({ className, children, ...props }, ref) => (
|
|
178
|
+
<ContextMenuPrimitive.RadioItem
|
|
179
|
+
ref={ref}
|
|
180
|
+
className={cn(
|
|
181
|
+
"relative flex flex-row web:cursor-default web:group items-center rounded-sm py-1.5 native:py-2 pl-8 pr-2 web:outline-none web:focus:bg-accent active:bg-accent",
|
|
182
|
+
props.disabled && "web:pointer-events-none opacity-50",
|
|
183
|
+
className
|
|
184
|
+
)}
|
|
185
|
+
{...props}
|
|
186
|
+
>
|
|
187
|
+
<View className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
188
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
189
|
+
<View className="bg-foreground h-2 w-2 rounded-full" />
|
|
190
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
191
|
+
</View>
|
|
192
|
+
<>{children}</>
|
|
193
|
+
</ContextMenuPrimitive.RadioItem>
|
|
194
|
+
));
|
|
195
|
+
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
|
|
196
|
+
|
|
197
|
+
const ContextMenuLabel = React.forwardRef<
|
|
198
|
+
ContextMenuPrimitive.LabelRef,
|
|
199
|
+
ContextMenuPrimitive.LabelProps & {
|
|
200
|
+
inset?: boolean;
|
|
201
|
+
}
|
|
202
|
+
>(({ className, inset, ...props }, ref) => (
|
|
203
|
+
<ContextMenuPrimitive.Label
|
|
204
|
+
ref={ref}
|
|
205
|
+
className={cn(
|
|
206
|
+
"px-2 py-1.5 text-sm native:text-base font-semibold text-foreground web:cursor-default",
|
|
207
|
+
inset && "pl-8",
|
|
208
|
+
className
|
|
209
|
+
)}
|
|
210
|
+
{...props}
|
|
211
|
+
/>
|
|
212
|
+
));
|
|
213
|
+
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
|
|
214
|
+
|
|
215
|
+
const ContextMenuSeparator = React.forwardRef<
|
|
216
|
+
ContextMenuPrimitive.SeparatorRef,
|
|
217
|
+
ContextMenuPrimitive.SeparatorProps
|
|
218
|
+
>(({ className, ...props }, ref) => (
|
|
219
|
+
<ContextMenuPrimitive.Separator
|
|
220
|
+
ref={ref}
|
|
221
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
222
|
+
{...props}
|
|
223
|
+
/>
|
|
224
|
+
));
|
|
225
|
+
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
|
|
226
|
+
|
|
227
|
+
const ContextMenuShortcut = ({ className, ...props }: TextProps) => {
|
|
228
|
+
return (
|
|
229
|
+
<Text
|
|
230
|
+
className={cn(
|
|
231
|
+
"ml-auto text-xs native:text-sm tracking-widest text-muted-foreground",
|
|
232
|
+
className
|
|
233
|
+
)}
|
|
234
|
+
{...props}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
};
|
|
238
|
+
ContextMenuShortcut.displayName = "ContextMenuShortcut";
|
|
239
|
+
|
|
240
|
+
export {
|
|
241
|
+
ContextMenu,
|
|
242
|
+
ContextMenuCheckboxItem,
|
|
243
|
+
ContextMenuContent,
|
|
244
|
+
ContextMenuGroup,
|
|
245
|
+
ContextMenuItem,
|
|
246
|
+
ContextMenuLabel,
|
|
247
|
+
ContextMenuRadioGroup,
|
|
248
|
+
ContextMenuRadioItem,
|
|
249
|
+
ContextMenuSeparator,
|
|
250
|
+
ContextMenuShortcut,
|
|
251
|
+
ContextMenuSub,
|
|
252
|
+
ContextMenuSubContent,
|
|
253
|
+
ContextMenuSubTrigger,
|
|
254
|
+
ContextMenuTrigger
|
|
255
|
+
};
|