@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,192 @@
|
|
|
1
|
+
import * as SelectPrimitive from "@rn-primitives/select";
|
|
2
|
+
import { Check, ChevronDown, ChevronUp } from "lucide-react-native";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Platform, StyleSheet, View } from "react-native";
|
|
5
|
+
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
|
|
6
|
+
import { cn } from "../utils";
|
|
7
|
+
|
|
8
|
+
type Option = SelectPrimitive.Option;
|
|
9
|
+
|
|
10
|
+
const Select = SelectPrimitive.Root;
|
|
11
|
+
|
|
12
|
+
const SelectGroup = SelectPrimitive.Group;
|
|
13
|
+
|
|
14
|
+
const SelectValue = SelectPrimitive.Value;
|
|
15
|
+
|
|
16
|
+
const SelectTrigger = React.forwardRef<
|
|
17
|
+
SelectPrimitive.TriggerRef,
|
|
18
|
+
SelectPrimitive.TriggerProps
|
|
19
|
+
>(({ className, children, ...props }, ref) => (
|
|
20
|
+
<SelectPrimitive.Trigger
|
|
21
|
+
ref={ref}
|
|
22
|
+
className={cn(
|
|
23
|
+
"flex flex-row h-10 native:h-12 items-center text-sm justify-between rounded-md border border-input bg-background px-3 py-2 web:ring-offset-background text-muted-foreground web:focus:outline-none web:focus:ring-2 web:focus:ring-ring web:focus:ring-offset-2 [&>span]:line-clamp-1",
|
|
24
|
+
props.disabled && "web:cursor-not-allowed opacity-50",
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
<>{children}</>
|
|
30
|
+
<ChevronDown
|
|
31
|
+
size={16}
|
|
32
|
+
aria-hidden={true}
|
|
33
|
+
className="text-foreground opacity-50"
|
|
34
|
+
/>
|
|
35
|
+
</SelectPrimitive.Trigger>
|
|
36
|
+
));
|
|
37
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Platform: WEB ONLY
|
|
41
|
+
*/
|
|
42
|
+
const SelectScrollUpButton = ({
|
|
43
|
+
className,
|
|
44
|
+
...props
|
|
45
|
+
}: SelectPrimitive.ScrollUpButtonProps) => {
|
|
46
|
+
if (Platform.OS !== "web") {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return (
|
|
50
|
+
<SelectPrimitive.ScrollUpButton
|
|
51
|
+
className={cn(
|
|
52
|
+
"flex web:cursor-default items-center justify-center py-1",
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
>
|
|
57
|
+
<ChevronUp size={14} className="text-foreground" />
|
|
58
|
+
</SelectPrimitive.ScrollUpButton>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Platform: WEB ONLY
|
|
64
|
+
*/
|
|
65
|
+
const SelectScrollDownButton = ({
|
|
66
|
+
className,
|
|
67
|
+
...props
|
|
68
|
+
}: SelectPrimitive.ScrollDownButtonProps) => {
|
|
69
|
+
if (Platform.OS !== "web") {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return (
|
|
73
|
+
<SelectPrimitive.ScrollDownButton
|
|
74
|
+
className={cn(
|
|
75
|
+
"flex web:cursor-default items-center justify-center py-1",
|
|
76
|
+
className
|
|
77
|
+
)}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
<ChevronDown size={14} className="text-foreground" />
|
|
81
|
+
</SelectPrimitive.ScrollDownButton>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const SelectContent = React.forwardRef<
|
|
86
|
+
SelectPrimitive.ContentRef,
|
|
87
|
+
SelectPrimitive.ContentProps & { portalHost?: string }
|
|
88
|
+
>(({ className, children, position = "popper", portalHost, ...props }, ref) => {
|
|
89
|
+
const { open } = SelectPrimitive.useRootContext();
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<SelectPrimitive.Portal hostName={portalHost}>
|
|
93
|
+
<SelectPrimitive.Overlay
|
|
94
|
+
style={Platform.OS !== "web" ? StyleSheet.absoluteFill : undefined}
|
|
95
|
+
>
|
|
96
|
+
<Animated.View className="z-50" entering={FadeIn} exiting={FadeOut}>
|
|
97
|
+
<SelectPrimitive.Content
|
|
98
|
+
ref={ref}
|
|
99
|
+
className={cn(
|
|
100
|
+
"relative z-50 max-h-96 min-w-[8rem] rounded-md border border-border bg-popover shadow-md shadow-foreground/10 py-2 px-1 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",
|
|
101
|
+
position === "popper" &&
|
|
102
|
+
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
103
|
+
open
|
|
104
|
+
? "web:zoom-in-95 web:animate-in web:fade-in-0"
|
|
105
|
+
: "web:zoom-out-95 web:animate-out web:fade-out-0",
|
|
106
|
+
className
|
|
107
|
+
)}
|
|
108
|
+
position={position}
|
|
109
|
+
{...props}
|
|
110
|
+
>
|
|
111
|
+
<SelectScrollUpButton />
|
|
112
|
+
<SelectPrimitive.Viewport
|
|
113
|
+
className={cn(
|
|
114
|
+
"p-1",
|
|
115
|
+
position === "popper" &&
|
|
116
|
+
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
117
|
+
)}
|
|
118
|
+
>
|
|
119
|
+
{children}
|
|
120
|
+
</SelectPrimitive.Viewport>
|
|
121
|
+
<SelectScrollDownButton />
|
|
122
|
+
</SelectPrimitive.Content>
|
|
123
|
+
</Animated.View>
|
|
124
|
+
</SelectPrimitive.Overlay>
|
|
125
|
+
</SelectPrimitive.Portal>
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
129
|
+
|
|
130
|
+
const SelectLabel = React.forwardRef<
|
|
131
|
+
SelectPrimitive.LabelRef,
|
|
132
|
+
SelectPrimitive.LabelProps
|
|
133
|
+
>(({ className, ...props }, ref) => (
|
|
134
|
+
<SelectPrimitive.Label
|
|
135
|
+
ref={ref}
|
|
136
|
+
className={cn(
|
|
137
|
+
"py-1.5 native:pb-2 pl-8 native:pl-10 pr-2 text-popover-foreground text-sm native:text-base font-semibold",
|
|
138
|
+
className
|
|
139
|
+
)}
|
|
140
|
+
{...props}
|
|
141
|
+
/>
|
|
142
|
+
));
|
|
143
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
144
|
+
|
|
145
|
+
const SelectItem = React.forwardRef<
|
|
146
|
+
SelectPrimitive.ItemRef,
|
|
147
|
+
SelectPrimitive.ItemProps
|
|
148
|
+
>(({ className, children, ...props }, ref) => (
|
|
149
|
+
<SelectPrimitive.Item
|
|
150
|
+
ref={ref}
|
|
151
|
+
className={cn(
|
|
152
|
+
"relative web:group flex flex-row w-full web:cursor-default web:select-none items-center rounded-sm py-1.5 native:py-2 pl-8 native:pl-10 pr-2 web:hover:bg-accent/50 active:bg-accent web:outline-none web:focus:bg-accent",
|
|
153
|
+
props.disabled && "web:pointer-events-none opacity-50",
|
|
154
|
+
className
|
|
155
|
+
)}
|
|
156
|
+
{...props}
|
|
157
|
+
>
|
|
158
|
+
<View className="absolute left-2 native:left-3.5 flex h-3.5 native:pt-px w-3.5 items-center justify-center">
|
|
159
|
+
<SelectPrimitive.ItemIndicator>
|
|
160
|
+
<Check size={16} strokeWidth={3} className="text-popover-foreground" />
|
|
161
|
+
</SelectPrimitive.ItemIndicator>
|
|
162
|
+
</View>
|
|
163
|
+
<SelectPrimitive.ItemText className="text-sm native:text-lg text-popover-foreground native:text-base web:group-focus:text-accent-foreground" />
|
|
164
|
+
</SelectPrimitive.Item>
|
|
165
|
+
));
|
|
166
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
167
|
+
|
|
168
|
+
const SelectSeparator = React.forwardRef<
|
|
169
|
+
SelectPrimitive.SeparatorRef,
|
|
170
|
+
SelectPrimitive.SeparatorProps
|
|
171
|
+
>(({ className, ...props }, ref) => (
|
|
172
|
+
<SelectPrimitive.Separator
|
|
173
|
+
ref={ref}
|
|
174
|
+
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
|
175
|
+
{...props}
|
|
176
|
+
/>
|
|
177
|
+
));
|
|
178
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
Select,
|
|
182
|
+
SelectContent,
|
|
183
|
+
SelectGroup,
|
|
184
|
+
SelectItem,
|
|
185
|
+
SelectLabel,
|
|
186
|
+
SelectScrollDownButton,
|
|
187
|
+
SelectScrollUpButton,
|
|
188
|
+
SelectSeparator,
|
|
189
|
+
SelectTrigger,
|
|
190
|
+
SelectValue,
|
|
191
|
+
type Option
|
|
192
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as SeparatorPrimitive from "@rn-primitives/separator";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../utils";
|
|
4
|
+
|
|
5
|
+
const Separator = React.forwardRef<
|
|
6
|
+
SeparatorPrimitive.RootRef,
|
|
7
|
+
SeparatorPrimitive.RootProps
|
|
8
|
+
>(
|
|
9
|
+
(
|
|
10
|
+
{ className, orientation = "horizontal", decorative = true, ...props },
|
|
11
|
+
ref
|
|
12
|
+
) => (
|
|
13
|
+
<SeparatorPrimitive.Root
|
|
14
|
+
ref={ref}
|
|
15
|
+
decorative={decorative}
|
|
16
|
+
orientation={orientation}
|
|
17
|
+
className={cn(
|
|
18
|
+
"shrink-0 bg-border",
|
|
19
|
+
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
27
|
+
|
|
28
|
+
export { Separator };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Animated, {
|
|
3
|
+
useAnimatedStyle,
|
|
4
|
+
useSharedValue,
|
|
5
|
+
withRepeat,
|
|
6
|
+
withSequence,
|
|
7
|
+
withTiming
|
|
8
|
+
} from "react-native-reanimated";
|
|
9
|
+
import { cn } from "../utils";
|
|
10
|
+
|
|
11
|
+
const duration = 1000;
|
|
12
|
+
|
|
13
|
+
function Skeleton({
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}: Omit<React.ComponentPropsWithoutRef<typeof Animated.View>, "style">) {
|
|
17
|
+
const sv = useSharedValue(1);
|
|
18
|
+
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
sv.value = withRepeat(
|
|
21
|
+
withSequence(withTiming(0.5, { duration }), withTiming(1, { duration })),
|
|
22
|
+
-1
|
|
23
|
+
);
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
const style = useAnimatedStyle(() => ({
|
|
27
|
+
opacity: sv.value
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Animated.View
|
|
32
|
+
style={style}
|
|
33
|
+
className={cn("rounded-md bg-secondary dark:bg-muted", className)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { Skeleton };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import * as SwitchPrimitives from "@rn-primitives/switch";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Platform } from "react-native";
|
|
4
|
+
import Animated, {
|
|
5
|
+
interpolateColor,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
useDerivedValue,
|
|
8
|
+
withTiming
|
|
9
|
+
} from "react-native-reanimated";
|
|
10
|
+
import { useColorScheme } from "../hooks/useColorScheme";
|
|
11
|
+
import { cn } from "../utils";
|
|
12
|
+
|
|
13
|
+
const SwitchWeb = React.forwardRef<
|
|
14
|
+
SwitchPrimitives.RootRef,
|
|
15
|
+
SwitchPrimitives.RootProps
|
|
16
|
+
>(({ className, ...props }, ref) => (
|
|
17
|
+
<SwitchPrimitives.Root
|
|
18
|
+
className={cn(
|
|
19
|
+
"peer flex-row h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed",
|
|
20
|
+
props.checked ? "bg-primary" : "bg-input",
|
|
21
|
+
props.disabled && "opacity-50",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
ref={ref}
|
|
26
|
+
>
|
|
27
|
+
<SwitchPrimitives.Thumb
|
|
28
|
+
className={cn(
|
|
29
|
+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-md shadow-foreground/5 ring-0 transition-transform",
|
|
30
|
+
props.checked ? "translate-x-5" : "translate-x-0"
|
|
31
|
+
)}
|
|
32
|
+
/>
|
|
33
|
+
</SwitchPrimitives.Root>
|
|
34
|
+
));
|
|
35
|
+
|
|
36
|
+
SwitchWeb.displayName = "SwitchWeb";
|
|
37
|
+
|
|
38
|
+
const RGB_COLORS = {
|
|
39
|
+
light: {
|
|
40
|
+
primary: "rgb(24, 24, 27)",
|
|
41
|
+
input: "rgb(228, 228, 231)"
|
|
42
|
+
},
|
|
43
|
+
dark: {
|
|
44
|
+
primary: "rgb(250, 250, 250)",
|
|
45
|
+
input: "rgb(39, 39, 42)"
|
|
46
|
+
}
|
|
47
|
+
} as const;
|
|
48
|
+
|
|
49
|
+
const SwitchNative = React.forwardRef<
|
|
50
|
+
SwitchPrimitives.RootRef,
|
|
51
|
+
SwitchPrimitives.RootProps
|
|
52
|
+
>(({ className, ...props }, ref) => {
|
|
53
|
+
const { colorScheme } = useColorScheme();
|
|
54
|
+
const translateX = useDerivedValue(() => (props.checked ? 18 : 0));
|
|
55
|
+
const animatedRootStyle = useAnimatedStyle(() => {
|
|
56
|
+
return {
|
|
57
|
+
backgroundColor: interpolateColor(
|
|
58
|
+
translateX.value,
|
|
59
|
+
[0, 18],
|
|
60
|
+
[RGB_COLORS[colorScheme].input, RGB_COLORS[colorScheme].primary]
|
|
61
|
+
)
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
const animatedThumbStyle = useAnimatedStyle(() => ({
|
|
65
|
+
transform: [{ translateX: withTiming(translateX.value, { duration: 200 }) }]
|
|
66
|
+
}));
|
|
67
|
+
return (
|
|
68
|
+
<Animated.View
|
|
69
|
+
style={animatedRootStyle}
|
|
70
|
+
className={cn(
|
|
71
|
+
"h-8 w-[46px] rounded-full",
|
|
72
|
+
props.disabled && "opacity-50"
|
|
73
|
+
)}
|
|
74
|
+
>
|
|
75
|
+
<SwitchPrimitives.Root
|
|
76
|
+
className={cn(
|
|
77
|
+
"flex-row h-8 w-[46px] shrink-0 items-center rounded-full border-2 border-transparent",
|
|
78
|
+
props.checked ? "bg-primary" : "bg-input",
|
|
79
|
+
className
|
|
80
|
+
)}
|
|
81
|
+
{...props}
|
|
82
|
+
ref={ref}
|
|
83
|
+
>
|
|
84
|
+
<Animated.View style={animatedThumbStyle}>
|
|
85
|
+
<SwitchPrimitives.Thumb
|
|
86
|
+
className={
|
|
87
|
+
"h-7 w-7 rounded-full bg-background shadow-md shadow-foreground/25 ring-0"
|
|
88
|
+
}
|
|
89
|
+
/>
|
|
90
|
+
</Animated.View>
|
|
91
|
+
</SwitchPrimitives.Root>
|
|
92
|
+
</Animated.View>
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
SwitchNative.displayName = "SwitchNative";
|
|
96
|
+
|
|
97
|
+
const Switch = Platform.select({
|
|
98
|
+
web: SwitchWeb,
|
|
99
|
+
default: SwitchNative
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export { Switch };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as TablePrimitive from "@rn-primitives/table";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../utils";
|
|
4
|
+
import { TextClassContext } from "./text";
|
|
5
|
+
|
|
6
|
+
const Table = React.forwardRef<
|
|
7
|
+
TablePrimitive.RootRef,
|
|
8
|
+
TablePrimitive.RootProps
|
|
9
|
+
>(({ className, ...props }, ref) => (
|
|
10
|
+
<TablePrimitive.Root
|
|
11
|
+
ref={ref}
|
|
12
|
+
className={cn("w-full caption-bottom text-sm", className)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
));
|
|
16
|
+
Table.displayName = "Table";
|
|
17
|
+
|
|
18
|
+
const TableHeader = React.forwardRef<
|
|
19
|
+
TablePrimitive.HeaderRef,
|
|
20
|
+
TablePrimitive.HeaderProps
|
|
21
|
+
>(({ className, ...props }, ref) => (
|
|
22
|
+
<TablePrimitive.Header
|
|
23
|
+
ref={ref}
|
|
24
|
+
className={cn("border-border [&_tr]:border-b", className)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
));
|
|
28
|
+
TableHeader.displayName = "TableHeader";
|
|
29
|
+
|
|
30
|
+
const TableBody = React.forwardRef<
|
|
31
|
+
TablePrimitive.BodyRef,
|
|
32
|
+
TablePrimitive.BodyProps
|
|
33
|
+
>(({ className, style, ...props }, ref) => (
|
|
34
|
+
<TablePrimitive.Body
|
|
35
|
+
ref={ref}
|
|
36
|
+
className={cn("flex-1 border-border [&_tr:last-child]:border-0", className)}
|
|
37
|
+
style={[{ minHeight: 2 }, style]}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
));
|
|
41
|
+
TableBody.displayName = "TableBody";
|
|
42
|
+
|
|
43
|
+
const TableFooter = React.forwardRef<
|
|
44
|
+
TablePrimitive.FooterRef,
|
|
45
|
+
TablePrimitive.FooterProps
|
|
46
|
+
>(({ className, ...props }, ref) => (
|
|
47
|
+
<TablePrimitive.Footer
|
|
48
|
+
ref={ref}
|
|
49
|
+
className={cn("bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
));
|
|
53
|
+
TableFooter.displayName = "TableFooter";
|
|
54
|
+
|
|
55
|
+
const TableRow = React.forwardRef<
|
|
56
|
+
TablePrimitive.RowRef,
|
|
57
|
+
TablePrimitive.RowProps
|
|
58
|
+
>(({ className, ...props }, ref) => (
|
|
59
|
+
<TablePrimitive.Row
|
|
60
|
+
ref={ref}
|
|
61
|
+
className={cn(
|
|
62
|
+
"flex-row border-border border-b web:transition-colors web:hover:bg-muted/50 web:data-[state=selected]:bg-muted",
|
|
63
|
+
className
|
|
64
|
+
)}
|
|
65
|
+
{...props}
|
|
66
|
+
/>
|
|
67
|
+
));
|
|
68
|
+
TableRow.displayName = "TableRow";
|
|
69
|
+
|
|
70
|
+
const TableHead = React.forwardRef<
|
|
71
|
+
TablePrimitive.HeadRef,
|
|
72
|
+
TablePrimitive.HeadProps
|
|
73
|
+
>(({ className, ...props }, ref) => (
|
|
74
|
+
<TextClassContext.Provider value="text-muted-foreground">
|
|
75
|
+
<TablePrimitive.Head
|
|
76
|
+
ref={ref}
|
|
77
|
+
className={cn(
|
|
78
|
+
"h-12 px-4 text-left justify-center font-medium [&:has([role=checkbox])]:pr-0",
|
|
79
|
+
className
|
|
80
|
+
)}
|
|
81
|
+
{...props}
|
|
82
|
+
/>
|
|
83
|
+
</TextClassContext.Provider>
|
|
84
|
+
));
|
|
85
|
+
TableHead.displayName = "TableHead";
|
|
86
|
+
|
|
87
|
+
const TableCell = React.forwardRef<
|
|
88
|
+
TablePrimitive.CellRef,
|
|
89
|
+
TablePrimitive.CellProps
|
|
90
|
+
>(({ className, ...props }, ref) => (
|
|
91
|
+
<TablePrimitive.Cell
|
|
92
|
+
ref={ref}
|
|
93
|
+
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
));
|
|
97
|
+
TableCell.displayName = "TableCell";
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
Table,
|
|
101
|
+
TableBody,
|
|
102
|
+
TableCell,
|
|
103
|
+
TableFooter,
|
|
104
|
+
TableHead,
|
|
105
|
+
TableHeader,
|
|
106
|
+
TableRow
|
|
107
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as TabsPrimitive from "@rn-primitives/tabs";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../utils";
|
|
4
|
+
import { TextClassContext } from "./text";
|
|
5
|
+
|
|
6
|
+
const Tabs = TabsPrimitive.Root;
|
|
7
|
+
|
|
8
|
+
const TabsList = React.forwardRef<
|
|
9
|
+
TabsPrimitive.ListRef,
|
|
10
|
+
TabsPrimitive.ListProps
|
|
11
|
+
>(({ className, ...props }, ref) => (
|
|
12
|
+
<TabsPrimitive.List
|
|
13
|
+
ref={ref}
|
|
14
|
+
className={cn(
|
|
15
|
+
"web:inline-flex h-10 native:h-12 items-center justify-center rounded-md bg-muted p-1 native:px-1.5",
|
|
16
|
+
className
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
));
|
|
21
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
22
|
+
|
|
23
|
+
const TabsTrigger = React.forwardRef<
|
|
24
|
+
TabsPrimitive.TriggerRef,
|
|
25
|
+
TabsPrimitive.TriggerProps
|
|
26
|
+
>(({ className, ...props }, ref) => {
|
|
27
|
+
const { value } = TabsPrimitive.useRootContext();
|
|
28
|
+
return (
|
|
29
|
+
<TextClassContext.Provider
|
|
30
|
+
value={cn(
|
|
31
|
+
"text-sm native:text-base font-medium text-muted-foreground web:transition-all",
|
|
32
|
+
value === props.value && "text-foreground"
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
<TabsPrimitive.Trigger
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn(
|
|
38
|
+
"inline-flex items-center justify-center shadow-none web:whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium web:ring-offset-background web:transition-all web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2",
|
|
39
|
+
props.disabled && "web:pointer-events-none opacity-50",
|
|
40
|
+
props.value === value &&
|
|
41
|
+
"bg-background shadow-lg shadow-foreground/10",
|
|
42
|
+
className
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
</TextClassContext.Provider>
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
50
|
+
|
|
51
|
+
const TabsContent = React.forwardRef<
|
|
52
|
+
TabsPrimitive.ContentRef,
|
|
53
|
+
TabsPrimitive.ContentProps
|
|
54
|
+
>(({ className, ...props }, ref) => (
|
|
55
|
+
<TabsPrimitive.Content
|
|
56
|
+
ref={ref}
|
|
57
|
+
className={cn(
|
|
58
|
+
"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",
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
));
|
|
64
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
65
|
+
|
|
66
|
+
export { Tabs, TabsContent, TabsList, TabsTrigger };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as Slot from "@rn-primitives/slot";
|
|
2
|
+
import type { SlottableTextProps, TextRef } from "@rn-primitives/types";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Text as RNText } from "react-native";
|
|
5
|
+
import { cn } from "../utils";
|
|
6
|
+
|
|
7
|
+
const TextClassContext = React.createContext<string | undefined>(undefined);
|
|
8
|
+
|
|
9
|
+
const Text = React.forwardRef<TextRef, SlottableTextProps>(
|
|
10
|
+
({ className, asChild = false, ...props }, ref) => {
|
|
11
|
+
const textClass = React.useContext(TextClassContext);
|
|
12
|
+
const Component = asChild ? Slot.Text : RNText;
|
|
13
|
+
return (
|
|
14
|
+
<Component
|
|
15
|
+
className={cn(
|
|
16
|
+
"text-base text-foreground web:select-text",
|
|
17
|
+
textClass,
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
ref={ref}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
Text.displayName = "Text";
|
|
27
|
+
|
|
28
|
+
export { Text, TextClassContext };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { TextInput, type TextInputProps } from "react-native";
|
|
3
|
+
import { cn } from "../utils";
|
|
4
|
+
|
|
5
|
+
const Textarea = React.forwardRef<
|
|
6
|
+
React.ElementRef<typeof TextInput>,
|
|
7
|
+
TextInputProps
|
|
8
|
+
>(
|
|
9
|
+
(
|
|
10
|
+
{
|
|
11
|
+
className,
|
|
12
|
+
multiline = true,
|
|
13
|
+
numberOfLines = 4,
|
|
14
|
+
placeholderClassName,
|
|
15
|
+
...props
|
|
16
|
+
},
|
|
17
|
+
ref
|
|
18
|
+
) => {
|
|
19
|
+
return (
|
|
20
|
+
<TextInput
|
|
21
|
+
ref={ref}
|
|
22
|
+
className={cn(
|
|
23
|
+
"web:flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base lg:text-sm native:text-lg native:leading-[1.25] text-foreground web:ring-offset-background placeholder:text-muted-foreground web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2",
|
|
24
|
+
props.editable === false && "opacity-50 web:cursor-not-allowed",
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
placeholderClassName={cn("text-muted-foreground", placeholderClassName)}
|
|
28
|
+
multiline={multiline}
|
|
29
|
+
numberOfLines={numberOfLines}
|
|
30
|
+
textAlignVertical="top"
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
Textarea.displayName = "Textarea";
|
|
38
|
+
|
|
39
|
+
export { Textarea };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as ToggleGroupPrimitive from "@rn-primitives/toggle-group";
|
|
2
|
+
import type { VariantProps } from "class-variance-authority";
|
|
3
|
+
import type { LucideIcon } from "lucide-react-native";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { cn } from "../utils";
|
|
6
|
+
import { TextClassContext } from "./text";
|
|
7
|
+
import { toggleTextVariants, toggleVariants } from "./toggle";
|
|
8
|
+
|
|
9
|
+
const ToggleGroupContext = React.createContext<VariantProps<
|
|
10
|
+
typeof toggleVariants
|
|
11
|
+
> | null>(null);
|
|
12
|
+
|
|
13
|
+
const ToggleGroup = React.forwardRef<
|
|
14
|
+
ToggleGroupPrimitive.RootRef,
|
|
15
|
+
ToggleGroupPrimitive.RootProps & VariantProps<typeof toggleVariants>
|
|
16
|
+
>(({ className, variant, size, children, ...props }, ref) => (
|
|
17
|
+
<ToggleGroupPrimitive.Root
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn("flex flex-row items-center justify-center gap-1", className)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
<ToggleGroupContext.Provider value={{ variant, size }}>
|
|
23
|
+
{children}
|
|
24
|
+
</ToggleGroupContext.Provider>
|
|
25
|
+
</ToggleGroupPrimitive.Root>
|
|
26
|
+
));
|
|
27
|
+
|
|
28
|
+
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
|
|
29
|
+
|
|
30
|
+
function useToggleGroupContext() {
|
|
31
|
+
const context = React.useContext(ToggleGroupContext);
|
|
32
|
+
if (context === null) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
"ToggleGroup compound components cannot be rendered outside the ToggleGroup component"
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
return context;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const ToggleGroupItem = React.forwardRef<
|
|
41
|
+
ToggleGroupPrimitive.ItemRef,
|
|
42
|
+
ToggleGroupPrimitive.ItemProps & VariantProps<typeof toggleVariants>
|
|
43
|
+
>(({ className, children, variant, size, ...props }, ref) => {
|
|
44
|
+
const context = useToggleGroupContext();
|
|
45
|
+
const { value } = ToggleGroupPrimitive.useRootContext();
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<TextClassContext.Provider
|
|
49
|
+
value={cn(
|
|
50
|
+
toggleTextVariants({ variant, size }),
|
|
51
|
+
ToggleGroupPrimitive.utils.getIsSelected(value, props.value)
|
|
52
|
+
? "text-accent-foreground"
|
|
53
|
+
: "web:group-hover:text-muted-foreground"
|
|
54
|
+
)}
|
|
55
|
+
>
|
|
56
|
+
<ToggleGroupPrimitive.Item
|
|
57
|
+
ref={ref}
|
|
58
|
+
className={cn(
|
|
59
|
+
toggleVariants({
|
|
60
|
+
variant: context.variant || variant,
|
|
61
|
+
size: context.size || size
|
|
62
|
+
}),
|
|
63
|
+
props.disabled && "web:pointer-events-none opacity-50",
|
|
64
|
+
ToggleGroupPrimitive.utils.getIsSelected(value, props.value) &&
|
|
65
|
+
"bg-accent",
|
|
66
|
+
className
|
|
67
|
+
)}
|
|
68
|
+
{...props}
|
|
69
|
+
>
|
|
70
|
+
{children}
|
|
71
|
+
</ToggleGroupPrimitive.Item>
|
|
72
|
+
</TextClassContext.Provider>
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
|
|
77
|
+
|
|
78
|
+
function ToggleGroupIcon({
|
|
79
|
+
className,
|
|
80
|
+
icon: Icon,
|
|
81
|
+
...props
|
|
82
|
+
}: React.ComponentPropsWithoutRef<LucideIcon> & {
|
|
83
|
+
icon: LucideIcon;
|
|
84
|
+
}) {
|
|
85
|
+
const textClass = React.useContext(TextClassContext);
|
|
86
|
+
return <Icon className={cn(textClass, className)} {...props} />;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { ToggleGroup, ToggleGroupIcon, ToggleGroupItem };
|