hold action mobile + najva token updated

This commit is contained in:
hamid zarghami
2025-07-28 12:43:37 +03:30
parent 80114f6fc7
commit f67336eebe
5 changed files with 122 additions and 52 deletions
+87 -24
View File
@@ -1,4 +1,4 @@
import React, { Fragment, useState } from 'react';
import React, { Fragment, useState, useRef } from 'react';
import DefaultTableSkeleton from './DefaultTableSkeleton';
import Td from './Td';
import { TableProps, RowDataType, ColumnType } from './types/TableTypes';
@@ -31,6 +31,9 @@ const Table = <T extends RowDataType>({
}: TableProps<T>): React.ReactElement => {
const [internalSelectedRows, setInternalSelectedRows] = useState<T[]>([]);
const [mobileSelectionMode, setMobileSelectionMode] = useState(false);
const longPressTimer = useRef<number | null>(null);
const [longPressActiveId, setLongPressActiveId] = useState<string | number | null>(null);
// استفاده از selectedRows خارجی اگر موجود باشد، در غیر این صورت از internal استفاده کن
const selectedRows = externalSelectedRows !== undefined ? externalSelectedRows : internalSelectedRows;
@@ -40,8 +43,59 @@ const Table = <T extends RowDataType>({
if (clearSelection && externalSelectedRows === undefined) {
setInternalSelectedRows([]);
}
// خروج از حالت انتخاب موبایل هم
if (clearSelection) {
setMobileSelectionMode(false);
}
}, [clearSelection, externalSelectedRows]);
// تمیز کردن timer هنگام unmount
React.useEffect(() => {
return () => {
if (longPressTimer.current) {
clearTimeout(longPressTimer.current);
}
};
}, []);
// خروج از حالت انتخاب اگر هیچ آیتمی انتخاب نشده
React.useEffect(() => {
if (selectedRows.length === 0 && mobileSelectionMode) {
setMobileSelectionMode(false);
}
}, [selectedRows.length, mobileSelectionMode]);
const handleLongPressStart = (item: T) => {
if (!selectable || mobileSelectionMode) return;
setLongPressActiveId(item.id);
longPressTimer.current = window.setTimeout(() => {
setMobileSelectionMode(true);
// انتخاب آیتم فعلی
handleSingleRowSelect(item, true);
setLongPressActiveId(null);
}, 500); // 500ms برای long press
};
const handleLongPressEnd = () => {
if (longPressTimer.current) {
clearTimeout(longPressTimer.current);
longPressTimer.current = null;
}
setLongPressActiveId(null);
};
const handleMobileRowClick = (item: T) => {
if (mobileSelectionMode) {
// در حالت انتخاب، آیتم را انتخاب/عدم انتخاب کن
const isSelected = isRowSelected(item);
handleSingleRowSelect(item, !isSelected);
} else if (longPressActiveId !== item.id) {
// در حالت عادی، row click عادی را اجرا کن
handleRowClick(item);
}
};
const getRowClassName = (item: T, index: number): string => {
if (typeof rowClassName === 'function') {
return rowClassName(item, index);
@@ -136,36 +190,24 @@ const Table = <T extends RowDataType>({
return (
<div
key={item.id}
className={`w-full min-h-[85px] ${bgColor} ${hoverColor} ${onRowClick ? 'cursor-pointer' : ''} ${getRowClassName(item, rowIndex)} px-4 py-3 flex items-center gap-3 ${rowIndex !== 0 ? 'border-t border-[#EAEDF5]' : ''}`}
onClick={() => handleRowClick(item)}
className={`w-full min-h-[85px] ${bgColor} ${hoverColor} ${mobileSelectionMode || !onRowClick ? '' : 'cursor-pointer'} ${getRowClassName(item, rowIndex)} px-4 py-3 flex items-center gap-3 ${rowIndex !== 0 ? 'border-t border-[#EAEDF5]' : ''} ${longPressActiveId === item.id ? 'bg-blue-50' : ''}`}
onClick={() => handleMobileRowClick(item)}
onTouchStart={() => handleLongPressStart(item)}
onTouchEnd={handleLongPressEnd}
onTouchCancel={handleLongPressEnd}
onMouseDown={() => handleLongPressStart(item)}
onMouseUp={handleLongPressEnd}
onMouseLeave={handleLongPressEnd}
>
{selectable && (
{selectable && mobileSelectionMode && (
<div
className="flex-shrink-0 "
className="flex-shrink-0"
onClick={(e) => e.stopPropagation()}
>
<Checkbox
checked={isRowSelected(item)}
onCheckedChange={(checked) => handleSingleRowSelect(item, !!checked)}
/>
{/* {inlineActions && (
<div
className="flex-shrink-0 flex items-center gap-2 "
onClick={(e) => e.stopPropagation()}
>
{inlineActions(item).map((action, actionIndex) => (
<div
key={actionIndex}
className={`cursor-pointer ${action.className || ''}`}
onClick={action.onClick}
title={action.tooltip}
>
{action.icon}
</div>
))}
</div>
)} */}
</div>
)}
@@ -341,11 +383,32 @@ const Table = <T extends RowDataType>({
{/* نسخه موبایل - Gmail style */}
<div className={`md:hidden`}>
{(actionsPosition === 'top' || actionsPosition === 'above-header') && (
<div className="h-[64px] bg-white flex items-center px-4 rounded-t-2xl border-b border-[#EAEDF5]">
<div className="h-[64px] bg-white flex items-center justify-between px-4 rounded-t-2xl border-b border-[#EAEDF5]">
<div className='flex items-center gap-2'>
{actions}
{selectable && selectedRows.length > 0 && selectedActions && selectedActions}
</div>
{mobileSelectionMode && (
<button
onClick={() => {
setMobileSelectionMode(false);
// پاک کردن انتخاب‌ها
if (externalSelectedRows !== undefined) {
if (onSelectionChange) {
onSelectionChange([]);
}
} else {
setInternalSelectedRows([]);
if (onSelectionChange) {
onSelectionChange([]);
}
}
}}
className="text-sm text-gray-600 px-3 py-1"
>
انصراف
</button>
)}
</div>
)}
{renderGmailStyleRows()}