Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/(site)/docs/components/badge/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function BadgePage() {
{
"title": "Sizes",
"value": "sizes",
"content": "import { Badge } from \"@nativeui/ui\";\n\nexport default function BadgeSizes() {\n return (\n <div className=\"flex items-center gap-4\">\n <Badge size=\"default\">Default</Badge>\n <Badge size=\"sm\">Sm</Badge>\n <Badge size=\"lg\">Lg</Badge>\n </div>\n );\n}",
"content": "import { Badge } from \"@components/ui\";\n\nexport default function BadgeSizes() {\n return (\n <div className=\"flex items-center gap-4\">\n <Badge size=\"default\">Default</Badge>\n <Badge size=\"sm\">Sm</Badge>\n <Badge size=\"lg\">Lg</Badge>\n </div>\n );\n}",
"language": "tsx"
}
]}
Expand Down
2 changes: 1 addition & 1 deletion app/(site)/docs/components/button/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function ButtonPage() {
{
"title": "Sizes",
"value": "sizes",
"content": "import { Button } from \"@nativeui/ui\";\n\nexport default function ButtonSizes() {\n return (\n <div className=\"flex items-center gap-4\">\n <Button size=\"default\">Default</Button>\n <Button size=\"sm\">Sm</Button>\n <Button size=\"lg\">Lg</Button>\n <Button size=\"icon\">👋</Button>\n </div>\n );\n}",
"content": "import { Button } from \"@components/ui\";\n\nexport default function ButtonSizes() {\n return (\n <div className=\"flex items-center gap-4\">\n <Button size=\"default\">Default</Button>\n <Button size=\"sm\">Sm</Button>\n <Button size=\"lg\">Lg</Button>\n <Button size=\"icon\">👋</Button>\n </div>\n );\n}",
"language": "tsx"
}
]}
Expand Down
4 changes: 2 additions & 2 deletions public/r/accordion.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "accordion",
"type": "registry:component",
"type": "registry:ui",
"title": "Accordion",
"description": "A accordion component for React Native applications.",
"dependencies": [],
Expand All @@ -10,7 +10,7 @@
{
"path": "registry/accordion/accordion.tsx",
"content": "import * as React from 'react';\nimport { Pressable, View, Text, LayoutAnimation, Platform, UIManager } from 'react-native';\nimport { Feather } from '@expo/vector-icons';\nimport { cn } from '@/lib/utils';\n\n// Enable layout animation for Android\nif (Platform.OS === 'android') {\n if (UIManager.setLayoutAnimationEnabledExperimental) {\n UIManager.setLayoutAnimationEnabledExperimental(true);\n }\n}\n\ninterface AccordionContextValue {\n value: string[];\n onValueChange: (itemValue: string) => void;\n type: 'single' | 'multiple';\n}\n\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\nexport interface AccordionProps {\n type?: 'single' | 'multiple';\n collapsible?: boolean;\n value?: string[];\n onValueChange?: (value: string[]) => void;\n defaultValue?: string[];\n className?: string;\n children: React.ReactNode;\n}\n\nconst Accordion = ({\n type = 'single',\n collapsible = false,\n value,\n onValueChange,\n defaultValue,\n className,\n children,\n}: AccordionProps) => {\n const [state, setState] = React.useState<string[]>(value || defaultValue || []);\n\n const isControlled = value !== undefined;\n const accordionValue = isControlled ? value : state;\n\n const handleValueChange = React.useCallback((itemValue: string) => {\n const isSelected = accordionValue.includes(itemValue);\n\n let newValue: string[] = [];\n\n if (type === 'single') {\n if (isSelected) {\n newValue = collapsible ? [] : [itemValue];\n } else {\n newValue = [itemValue];\n }\n } else {\n if (isSelected) {\n newValue = accordionValue.filter((v) => v !== itemValue);\n } else {\n newValue = [...accordionValue, itemValue];\n }\n }\n\n if (!isControlled) {\n setState(newValue);\n }\n\n onValueChange?.(newValue);\n }, [accordionValue, collapsible, isControlled, onValueChange, type]);\n\n return (\n <AccordionContext.Provider value={{ value: accordionValue, onValueChange: handleValueChange, type }}>\n <View className={cn(\"w-full\", className)}>\n {children}\n </View>\n </AccordionContext.Provider>\n );\n};\n\ninterface AccordionItemProps {\n value: string;\n className?: string;\n children: React.ReactNode;\n}\n\nconst AccordionItem = ({ value, className, children }: AccordionItemProps) => {\n const context = React.useContext(AccordionContext);\n\n if (!context) {\n throw new Error('AccordionItem must be used within an Accordion');\n }\n\n const isExpanded = context.value.includes(value);\n\n return (\n <View className={cn(\"border-b border-border\", className)}>\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child as React.ReactElement<any>, {\n value,\n isExpanded,\n });\n }\n return child;\n })}\n </View>\n );\n};\n\ninterface AccordionTriggerProps {\n className?: string;\n children: React.ReactNode;\n value?: string;\n isExpanded?: boolean;\n}\n\nconst AccordionTrigger = ({\n className,\n children,\n value,\n isExpanded,\n}: AccordionTriggerProps) => {\n const context = React.useContext(AccordionContext);\n\n if (!context || value === undefined) {\n return null;\n }\n\n const iconRotation = isExpanded ? 180 : 0;\n\n const handlePress = () => {\n LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);\n context.onValueChange(value);\n };\n\n return (\n <Pressable\n onPress={handlePress}\n className={cn(\n \"flex-row items-center justify-between py-4\",\n className\n )}\n accessibilityRole=\"button\"\n accessibilityState={{ expanded: isExpanded }}\n accessibilityHint=\"Toggle accordion section\"\n >\n <View className=\"flex-1\">\n {typeof children === 'string' ? (\n <Text className=\"text-base font-medium text-foreground\">{children}</Text>\n ) : (\n children\n )}\n </View>\n <View style={{ transform: [{ rotate: `${iconRotation}deg` }] }}>\n <Feather name=\"chevron-down\" size={20} color=\"#888\" />\n </View>\n </Pressable>\n );\n};\n\ninterface AccordionContentProps {\n className?: string;\n children: React.ReactNode;\n value?: string;\n isExpanded?: boolean;\n}\n\nconst AccordionContent = ({\n className,\n children,\n value,\n isExpanded,\n}: AccordionContentProps) => {\n if (!isExpanded) {\n return null;\n }\n\n return (\n <View\n className={cn(\"pb-4 pt-0\", className)}\n >\n {typeof children === 'string' ? (\n <Text className=\"text-base text-muted-foreground\">{children}</Text>\n ) : (\n children\n )}\n </View>\n );\n};\n\nAccordion.displayName = 'Accordion';\nAccordionItem.displayName = 'AccordionItem';\nAccordionTrigger.displayName = 'AccordionTrigger';\nAccordionContent.displayName = 'AccordionContent';\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; ",
"type": "registry:component"
"type": "registry:ui"
}
],
"changelog": [],
Expand Down
4 changes: 2 additions & 2 deletions public/r/alert-dialog.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "alert-dialog",
"type": "registry:component",
"type": "registry:ui",
"title": "Alert-dialog",
"description": "A alert-dialog component for React Native applications.",
"dependencies": [],
Expand All @@ -10,7 +10,7 @@
{
"path": "registry/alert-dialog/alert-dialog.tsx",
"content": "import * as React from \"react\";\nimport {\n View,\n Text,\n Pressable,\n Modal,\n TouchableWithoutFeedback,\n Platform,\n Animated,\n Dimensions,\n KeyboardAvoidingView,\n} from \"react-native\";\nimport { cn } from \"@/lib/utils\";\n\ninterface AlertDialogProps {\n children: React.ReactNode;\n className?: string;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\ninterface AlertDialogTriggerProps {\n children: React.ReactNode;\n className?: string;\n disabled?: boolean;\n asChild?: boolean;\n}\n\ninterface AlertDialogContentProps {\n children: React.ReactNode;\n className?: string;\n onInteractOutside?: () => void;\n}\n\ninterface AlertDialogHeaderProps {\n className?: string;\n children: React.ReactNode;\n}\n\ninterface AlertDialogFooterProps {\n className?: string;\n children: React.ReactNode;\n}\n\ninterface AlertDialogTitleProps {\n className?: string;\n children: React.ReactNode;\n}\n\ninterface AlertDialogDescriptionProps {\n className?: string;\n children: React.ReactNode;\n}\n\ninterface AlertDialogActionProps {\n children: React.ReactElement<{ onPress?: (e: any) => void }>;\n className?: string;\n}\n\ninterface AlertDialogCancelProps {\n children: React.ReactElement<{ onPress?: (e: any) => void }>;\n className?: string;\n}\n\nconst AlertDialogContext = React.createContext<{\n open: boolean;\n setOpen: (open: boolean) => void;\n handleClose?: () => void;\n}>({\n open: false,\n setOpen: () => { },\n});\n\nconst AlertDialog = React.forwardRef<View, AlertDialogProps>(\n ({ children, className, open = false, onOpenChange, ...props }, ref) => {\n const [internalOpen, setInternalOpen] = React.useState(false);\n\n const isControlled = open !== undefined;\n const isOpen = isControlled ? open : internalOpen;\n\n const setOpen = React.useCallback(\n (value: boolean) => {\n if (!isControlled) {\n setInternalOpen(value);\n }\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange]\n );\n\n return (\n <AlertDialogContext.Provider value={{ open: isOpen, setOpen }}>\n <View ref={ref} className={cn(\"\", className)} {...props}>\n {children}\n </View>\n </AlertDialogContext.Provider>\n );\n }\n);\n\nAlertDialog.displayName = \"AlertDialog\";\n\nconst AlertDialogTrigger = React.forwardRef<View, AlertDialogTriggerProps>(\n (\n { children, className, disabled = false, asChild = false, ...props },\n ref\n ) => {\n const { setOpen } = React.useContext(AlertDialogContext);\n\n if (asChild) {\n const child = React.Children.only(children) as React.ReactElement<{\n onPress?: (e: any) => void;\n ref?: React.Ref<any>;\n disabled?: boolean;\n }>;\n return React.cloneElement(child, {\n ...props,\n ref,\n onPress: (e: any) => {\n child.props?.onPress?.(e);\n setOpen(true);\n },\n disabled,\n });\n }\n\n return (\n <Pressable\n ref={ref}\n className={cn(\"\", className)}\n disabled={disabled}\n onPress={() => setOpen(true)}\n accessibilityRole=\"button\"\n {...props}\n >\n {children}\n </Pressable>\n );\n }\n);\n\nAlertDialogTrigger.displayName = \"AlertDialogTrigger\";\n\nconst AlertDialogContent = React.forwardRef<View, AlertDialogContentProps>(\n ({ children, className, onInteractOutside, ...props }, ref) => {\n const { open, setOpen } = React.useContext(AlertDialogContext);\n const fadeAnim = React.useRef(new Animated.Value(0)).current;\n const scaleAnim = React.useRef(new Animated.Value(0.95)).current;\n const { height: SCREEN_HEIGHT } = Dimensions.get(\"window\");\n const [isVisible, setIsVisible] = React.useState(open);\n\n React.useEffect(() => {\n if (open && !isVisible) {\n setIsVisible(true);\n }\n }, [open, isVisible]);\n\n React.useEffect(() => {\n if (isVisible) {\n Animated.parallel([\n Animated.timing(fadeAnim, {\n toValue: 1,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.spring(scaleAnim, {\n toValue: 1,\n damping: 20,\n stiffness: 300,\n useNativeDriver: true,\n }),\n ]).start();\n }\n }, [isVisible, fadeAnim, scaleAnim]);\n\n const handleClose = React.useCallback(() => {\n Animated.parallel([\n Animated.timing(fadeAnim, {\n toValue: 0,\n duration: 150,\n useNativeDriver: true,\n }),\n Animated.timing(scaleAnim, {\n toValue: 0.95,\n duration: 150,\n useNativeDriver: true,\n }),\n ]).start(() => {\n setIsVisible(false);\n setOpen(false);\n });\n }, [fadeAnim, scaleAnim, setOpen]);\n\n if (!isVisible) return null;\n\n return (\n <AlertDialogContext.Provider\n value={{ open: isVisible, setOpen, handleClose }}\n >\n <Modal\n visible={isVisible}\n transparent\n statusBarTranslucent\n animationType=\"none\"\n onRequestClose={handleClose}\n >\n <TouchableWithoutFeedback\n onPress={() => {\n onInteractOutside?.();\n }}\n >\n <Animated.View\n className=\"flex-1 justify-center items-center bg-black/50\"\n style={{ opacity: fadeAnim }}\n >\n <TouchableWithoutFeedback>\n <KeyboardAvoidingView\n behavior={Platform.OS === \"ios\" ? \"padding\" : undefined}\n keyboardVerticalOffset={\n Platform.OS === \"ios\" ? -SCREEN_HEIGHT * 0.2 : 0\n }\n >\n <Animated.View\n ref={ref}\n className={cn(\n \"bg-background m-6 rounded-2xl\",\n \"w-[85%] max-w-sm\",\n Platform.OS === \"ios\"\n ? \"ios:shadow-xl\"\n : \"android:elevation-8\",\n className\n )}\n style={{\n transform: [{ scale: scaleAnim }],\n }}\n {...props}\n >\n {children}\n </Animated.View>\n </KeyboardAvoidingView>\n </TouchableWithoutFeedback>\n </Animated.View>\n </TouchableWithoutFeedback>\n </Modal>\n </AlertDialogContext.Provider>\n );\n }\n);\n\nAlertDialogContent.displayName = \"AlertDialogContent\";\n\nconst AlertDialogHeader = React.forwardRef<View, AlertDialogHeaderProps>(\n ({ className, children, ...props }, ref) => (\n <View\n ref={ref}\n className={cn(\"flex-col gap-2 p-6 pb-0\", className)}\n {...props}\n >\n {children}\n </View>\n )\n);\n\nAlertDialogHeader.displayName = \"AlertDialogHeader\";\n\nconst AlertDialogFooter = React.forwardRef<View, AlertDialogFooterProps>(\n ({ className, children, ...props }, ref) => (\n <View\n ref={ref}\n className={cn(\n \"flex-row justify-end items-center gap-3 p-6 pt-4\",\n className\n )}\n {...props}\n >\n {children}\n </View>\n )\n);\n\nAlertDialogFooter.displayName = \"AlertDialogFooter\";\n\nconst AlertDialogTitle = React.forwardRef<Text, AlertDialogTitleProps>(\n ({ className, children, ...props }, ref) => (\n <Text\n ref={ref}\n className={cn(\n \"text-foreground text-xl font-semibold leading-none tracking-tight text-center\",\n className\n )}\n {...props}\n >\n {children}\n </Text>\n )\n);\n\nAlertDialogTitle.displayName = \"AlertDialogTitle\";\n\nconst AlertDialogDescription = React.forwardRef<\n Text,\n AlertDialogDescriptionProps\n>(({ className, children, ...props }, ref) => (\n <Text\n ref={ref}\n className={cn(\n \"text-muted-foreground text-base mt-2 text-center\",\n className\n )}\n {...props}\n >\n {children}\n </Text>\n));\n\nAlertDialogDescription.displayName = \"AlertDialogDescription\";\n\nconst AlertDialogAction = React.forwardRef<View, AlertDialogActionProps>(\n ({ children, ...props }, ref) => {\n const { handleClose } = React.useContext(AlertDialogContext);\n\n return React.cloneElement(children, {\n ...children.props,\n ...props,\n onPress: (e: any) => {\n children.props?.onPress?.(e);\n handleClose?.();\n },\n });\n }\n);\n\nAlertDialogAction.displayName = \"AlertDialogAction\";\n\nconst AlertDialogCancel = React.forwardRef<View, AlertDialogCancelProps>(\n ({ children, ...props }, ref) => {\n const { handleClose } = React.useContext(AlertDialogContext);\n\n return React.cloneElement(children, {\n ...children.props,\n ...props,\n onPress: (e: any) => {\n children.props?.onPress?.(e);\n handleClose?.();\n },\n });\n }\n);\n\nAlertDialogCancel.displayName = \"AlertDialogCancel\";\n\nexport {\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n",
"type": "registry:component"
"type": "registry:ui"
}
],
"changelog": [],
Expand Down
4 changes: 2 additions & 2 deletions public/r/alert.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "alert",
"type": "registry:component",
"type": "registry:ui",
"title": "Alert",
"description": "A alert component for React Native applications.",
"dependencies": [
Expand All @@ -12,7 +12,7 @@
{
"path": "registry/alert/alert.tsx",
"content": "import * as React from \"react\";\nimport { View, Text } from \"react-native\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst alertVariants = cva(\"w-full rounded-xl border p-4 mb-4\", {\n variants: {\n variant: {\n default: \"bg-background border-input\",\n destructive:\n \"border-destructive/50 bg-destructive/10 text-destructive dark:border-destructive\",\n success:\n \"border-green-500/50 bg-green-500/10 text-green-700 dark:text-green-500 dark:border-green-500\",\n warning:\n \"border-yellow-500/50 bg-yellow-500/10 text-yellow-700 dark:text-yellow-500 dark:border-yellow-500\",\n info: \"border-blue-500/50 bg-blue-500/10 text-blue-700 dark:text-blue-500 dark:border-blue-500\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n});\n\ninterface AlertProps\n extends React.ComponentPropsWithoutRef<typeof View>,\n VariantProps<typeof alertVariants> {\n icon?: React.ReactNode;\n}\n\nfunction Alert({ className, variant, icon, children, ...props }: AlertProps) {\n return (\n <View\n className={cn(alertVariants({ variant }), className)}\n accessibilityRole=\"alert\"\n {...props}\n >\n {icon && <View className=\"mb-2\">{icon}</View>}\n <View className={cn(icon ? \"pl-0\" : \"pl-0\")}>{children}</View>\n </View>\n );\n}\n\ninterface AlertTitleProps extends React.ComponentPropsWithoutRef<typeof Text> { }\n\nfunction AlertTitle({ className, ...props }: AlertTitleProps) {\n return (\n <Text\n className={cn(\n \"text-lg font-semibold leading-none tracking-tight text-foreground mb-2\",\n className\n )}\n {...props}\n />\n );\n}\n\ninterface AlertDescriptionProps\n extends React.ComponentPropsWithoutRef<typeof Text> { }\n\nfunction AlertDescription({ className, ...props }: AlertDescriptionProps) {\n return (\n <Text\n className={cn(\"text-base text-foreground opacity-90\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Alert,\n AlertTitle,\n AlertDescription,\n type AlertProps,\n type AlertTitleProps,\n type AlertDescriptionProps,\n};\n",
"type": "registry:component"
"type": "registry:ui"
}
],
"changelog": [],
Expand Down
Loading