修改日期问题弹出问题

This commit is contained in:
筱野
2026-02-07 22:15:14 +08:00
parent 6f73bb6d99
commit bfc6a149f0
12 changed files with 515 additions and 95 deletions

View File

@@ -0,0 +1,181 @@
import React, { useRef, useState } from 'react'
import type { CSSProperties, ReactNode } from 'react'
import { View, Text } from '@tarojs/components'
import { Button } from '@nutui/nutui-react-taro'
import styles from './index.module.scss'
export interface CustomPopupProps {
visible: boolean
onClose: () => void
title?: ReactNode
showHeader?: boolean
hideFooter?: boolean
cancelText?: string
confirmText?: string
onCancel?: () => void
onConfirm?: () => void
children?: ReactNode
className?: string
style?: CSSProperties
// 与 CommonPopup 保持入参一致
position?: 'center' | 'bottom' | 'top' | 'left' | 'right'
round?: boolean
zIndex?: number
enableDragToClose?: boolean
}
const CustomPopup: React.FC<CustomPopupProps> = ({
visible,
onClose,
title,
showHeader = false,
hideFooter = false,
cancelText = '返回',
confirmText = '完成',
onCancel,
onConfirm,
children,
className,
style,
position = 'bottom',
round = true,
zIndex,
enableDragToClose = true,
}) => {
const [dragOffset, setDragOffset] = useState(0)
const [isDragging, setIsDragging] = useState(false)
const touchStartY = useRef(0)
if (!visible) {
return null
}
const handleCancel = () => {
if (onCancel) {
onCancel()
} else {
onClose()
}
}
const handleTouchStart = (e: any) => {
if (!enableDragToClose) return
touchStartY.current = e.touches[0].clientY
setIsDragging(true)
}
const handleTouchMove = (e: any) => {
if (!enableDragToClose || !isDragging) return
const currentY = e.touches[0].clientY
const deltaY = currentY - touchStartY.current
if (deltaY > 0) {
setDragOffset(Math.min(deltaY, 100))
}
}
const handleTouchEnd = () => {
if (!enableDragToClose || !isDragging) return
setIsDragging(false)
if (dragOffset > 50) {
onClose()
}
setDragOffset(0)
}
const overlayAlignItems =
position === 'center'
? 'center'
: position === 'top'
? 'flex-start'
: 'flex-end'
const handleOverlayClick = () => {
onClose()
}
return (
<View
className={styles['custom-popup-overlay']}
style={{ zIndex: zIndex ?? undefined, alignItems: overlayAlignItems }}
onClick={handleOverlayClick}
>
<View className={styles['custom-popup-move']} catchMove></View>
<View
className={`${styles['custom-popup']} ${className ? className : ''}`}
style={{
...style,
}}
onClick={(e) => {
e.stopPropagation()
}}
>
{enableDragToClose && (
<View
className={styles['custom-popup__drag-handle-container']}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>
<View
className={styles['custom-popup__drag-handle']}
style={{
transform: `translateX(-50%) translateY(${dragOffset * 0.3}px)`,
opacity: isDragging ? 0.8 : 1,
transition: isDragging ? 'none' : 'all 0.3s ease-out',
}}
/>
</View>
)}
{showHeader && (
<View className={styles['custom-popup__header']}>
{typeof title === 'string' ? (
<Text className={styles['custom-popup__title']}>{title}</Text>
) : (
title
)}
<View className={styles['close_button']} onClick={onClose}>
<View className={styles['close_icon']}>
<View className={styles['close_line']} />
<View className={styles['close_line']} />
</View>
</View>
</View>
)}
<View className={styles['custom-popup__body']}>{children}</View>
{!hideFooter && (
<View className={styles['custom-popup__footer']}>
<Button
className={`${styles['custom-popup__btn']} ${styles['custom-popup__btn-cancel']}`}
type="default"
size="small"
onClick={handleCancel}
>
{cancelText}
</Button>
<Button
className={`${styles['custom-popup__btn']} ${styles['custom-popup__btn-confirm']}`}
type="primary"
size="small"
onClick={onConfirm}
>
{confirmText}
</Button>
</View>
)}
</View>
</View>
)
}
export default CustomPopup

View File

@@ -0,0 +1,153 @@
@use "~@/scss/themeColor.scss" as theme;
.custom-popup-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
display: flex;
align-items: flex-end;
justify-content: center;
}
.custom-popup-move{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9998;
}
.custom-popup {
position: relative;
z-index: 9999;
width: 100%;
padding: 0;
box-sizing: border-box;
max-height: 80vh;
display: flex;
flex-direction: column;
background-color: theme.$page-background-color;
border-radius: 20px 20px 0 0;
overflow: hidden;
.custom-popup__drag-handle-container {
position: relative;
height: 0;
}
.custom-popup__drag-handle {
position: absolute;
top: 6px;
left: 50%;
width: 90px;
height: 30px;
z-index: 10;
display: flex;
justify-content: center;
align-items: flex-start;
&::before {
content: "";
width: 32px;
height: 4px;
background-color: rgba(22, 24, 35, 0.2);
border-radius: 2px;
}
}
.custom-popup__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
.custom-popup__title {
font-family: "PingFang SC";
font-weight: 600;
font-size: 22px;
line-height: 1.27em;
color: #000000;
text-align: center;
}
.close_button {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 50%;
cursor: pointer;
box-shadow: 0px 4px 36px 0px rgba(0, 0, 0, 0.06);
.close_icon {
position: relative;
width: 24px;
height: 24px;
.close_line {
position: absolute;
top: 50%;
left: 50%;
width: 17px;
height: 3px;
border-radius: 3px;
background: #000000;
transform: translate(-50%, -50%) rotate(45deg);
&:nth-child(2) {
transform: translate(-50%, -50%) rotate(-45deg);
}
}
}
}
}
.custom-popup__body {
flex: 1 1 auto;
}
.custom-popup__footer {
padding: 8px 10px 0 10px;
display: flex;
gap: 8px;
background: #fafafa;
padding-bottom: max(10px, env(safe-area-inset-bottom));
}
.custom-popup__btn {
flex: 1;
font-feature-settings: "liga" off, "clig" off;
font-family: "PingFang SC";
font-size: 16px;
font-style: normal;
font-weight: 600;
line-height: normal;
}
.custom-popup__btn-cancel {
background: #f5f6f7;
color: #1f2329;
border: none;
width: 154px;
height: 44px;
border-radius: 12px !important;
border: 0.5px solid rgba(0, 0, 0, 0.06);
background: #fff;
padding: 4px 10px;
}
.custom-popup__btn-confirm {
width: 154px;
height: 44px;
border: 0.5px solid rgba(0, 0, 0, 0.06);
background: #000;
border-radius: 12px !important;
padding: 4px 10px;
}
}

View File

@@ -0,0 +1,4 @@
import CustomPopup from './CustomPopup'
export default CustomPopup
export * from './CustomPopup'