dialog.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { useEffect } from 'react'
  2. import { View, Text } from '@tarojs/components'
  3. import { cn } from '@/utils/cn'
  4. interface DialogProps {
  5. open: boolean
  6. onOpenChange: (open: boolean) => void
  7. children: React.ReactNode
  8. }
  9. export function Dialog({ open, onOpenChange, children }: DialogProps) {
  10. useEffect(() => {
  11. if (open) {
  12. // 在 Taro 中,我们可以使用模态框或者自定义弹窗
  13. // 这里使用自定义实现
  14. }
  15. }, [open])
  16. const handleBackdropClick = () => {
  17. onOpenChange(false)
  18. }
  19. const handleContentClick = (e: any) => {
  20. // 阻止事件冒泡,避免点击内容区域时关闭弹窗
  21. e.stopPropagation()
  22. }
  23. if (!open) return null
  24. return (
  25. <View
  26. className="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
  27. onClick={handleBackdropClick}
  28. >
  29. <View
  30. className="relative bg-white rounded-lg shadow-lg max-w-md w-full mx-4"
  31. onClick={handleContentClick}
  32. >
  33. {children}
  34. </View>
  35. </View>
  36. )
  37. }
  38. interface DialogContentProps {
  39. className?: string
  40. children: React.ReactNode
  41. }
  42. export function DialogContent({ className, children }: DialogContentProps) {
  43. return (
  44. <View className={cn("p-6", className)}>
  45. {children}
  46. </View>
  47. )
  48. }
  49. interface DialogHeaderProps {
  50. className?: string
  51. children: React.ReactNode
  52. }
  53. export function DialogHeader({ className, children }: DialogHeaderProps) {
  54. return (
  55. <View className={cn("mb-4", className)}>
  56. {children}
  57. </View>
  58. )
  59. }
  60. interface DialogTitleProps {
  61. className?: string
  62. children: React.ReactNode
  63. }
  64. export function DialogTitle({ className, children }: DialogTitleProps) {
  65. return (
  66. <Text className={cn("text-lg font-semibold text-gray-900", className)}>
  67. {children}
  68. </Text>
  69. )
  70. }
  71. interface DialogFooterProps {
  72. className?: string
  73. children: React.ReactNode
  74. }
  75. export function DialogFooter({ className, children }: DialogFooterProps) {
  76. return (
  77. <View className={cn("flex justify-end space-x-2", className)}>
  78. {children}
  79. </View>
  80. )
  81. }