Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(BodyCell): prevent cell or row refocus when overlay clicked #7401

Merged
merged 3 commits into from
Nov 8, 2024

Conversation

KumJungMin
Copy link
Contributor

@KumJungMin KumJungMin commented Nov 8, 2024

Defect Fixes


How To Resolve

Issue 1, Calendar Overlay Position Issue

  • Issue: When the cell is focused, the calendar overlay position behaves unexpectedly.
  • Cause: This occurs because the overlayRef of the Calendar is null when focused.
  • Solution: To resolve this, I added a setTimeout in the focus logic.
const focusOnElement = () => {
    clearTimeout(focusTimeout.current);
    focusTimeout.current = setTimeout(() => {  // Added!!
        if (editingState) {
            const focusableEl = props.editMode === 'cell' 
                ? DomHandler.getFirstFocusableElement(elementRef.current, ':not([data-pc-section="editorkeyhelperlabel"])') 
                : DomHandler.findSingle(elementRef.current, '[data-p-row-editor-save="true"]');

            focusableEl && focusableEl.focus();
        }

        keyHelperRef.current && (keyHelperRef.current.tabIndex = editingState ? -1 : 0);
    }, 1);
};

Issue 2, Calendar Overlay Cannot Select the Day Label Issue

  • Issue: When editingMeta is updated, the cell gains focus. Consequently, selecting a date in the calendar overlay updates the editingMeta value, causing the cell to regain focus repeatedly. As a result, even after selecting a date, the selected value remains null.
  • Cause: The update to editingMeta triggers the cell to regain focus, which interferes with the date selection process in the calendar overlay.
  • Solution: To address this, focusOnElement() and updateStickyPosition() are only invoked when editMode, editing, or editingState are updated.
React.useEffect(() => {
    if (getColumnProp('frozen')) {
        updateStickyPosition();
    }
    if (props.editMode === 'cell' || props.editMode === 'row') {
        focusOnElement();
    }
}, [props.editMode, props.editing, editingState]); // Updated to include dependencies

Issue 3, Focus Remains When Clicking Outside of the Cell

  • Issue: When clicking outside of the cell (Calendar), the cell remains focused.
  • Cause: The focus does not properly shift when clicking outside the cell.
  • Solution: To fix this, the scope of setTimeout was expanded to include the conditional statement for switchCellToViewMode.
listener: (e) => {
    setTimeout(() => { // Expanded setTimeout range
        if (!selfClick.current && isOutsideClicked(e.target)) {
            switchCellToViewMode(e, true);
        }
    }, 0);

    selfClick.current = false;
},

Test

sample code
import { Calendar } from '@/components/lib/calendar/Calendar';
import { DataTable } from '@/components/lib/datatable/DataTable';
import { Column } from '@/components/lib/column/Column';
import { useState, useCallback } from 'react';

export function BasicDoc() {
    return (
        <>
            <Test />
        </>
    );
}

const Test = () => {
    const [data, setData] = useState([
        { id: 1, date: null },
        { id: 2, date: '2024-01-01T00:00:00.000Z' },
        { id: 3, date: '2024-02-02T00:00:00.000Z' }
    ]);

    const formatDate = (date) => {
        return date ? new Date(date).toLocaleDateString('es-ES') : '';
    };

    const dateEditor = useCallback(
        (options, col) => {
            const value = options.value;
            const isValidDate = value && !isNaN(Date.parse(value));
            const dateValue = isValidDate ? new Date(value) : null;

            if (dateValue) {
                dateValue.setHours(12);
            }

            return (
                <Calendar
                    value={dateValue}
                    onChange={(e) => {
                        const selectedDate = e.value;

                        if (selectedDate) selectedDate.setHours(12);

                        const newData = [...data];
                        const index = options.rowIndex;

                        newData[index] = { ...newData[index], date: selectedDate };
                        setData(newData);
                        // console.log('newData', newData);
                        // console.log(selectedDate);
                        // console.log(options);
                        options.editorCallback(selectedDate);
                        // console.log(options);
                    }}
                    mask="99/99/9999"
                    dateFormat="dd/mm/yy"
                    showButtonBar
                    showIcon
                />
            );
        },
        [data]
    );

    return (
        <div className="card">
            <h3>TABLE</h3>
            <DataTable value={data} editMode="cell">
                <Column field="id" header="ID" />
                <Column
                    field="date"
                    header="Date"
                    body={(rowData) => formatDate(rowData.date)} // Usar formatDate para mostrar la fecha
                    editor={(options) => dateEditor(options, 'date')}
                    dataType="date"
                />
            </DataTable>
        </div>
    );
};

Before

  • When clicking the cell, the calendar overlay's position behaves unexpectedly.
  • When selecting a date in the calendar overlay, the selected value remains null.
2024-11-08.8.57.10.mov

After

383993426-35485802-4c37-406a-8395-1b7a7eba4331.mov

Copy link

vercel bot commented Nov 8, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Updated (UTC)
primereact ⬜️ Ignored (Inspect) Visit Preview Nov 8, 2024 0:08am
primereact-v9 ⬜️ Ignored (Inspect) Visit Preview Nov 8, 2024 0:08am

@melloware melloware added the Type: Bug Issue contains a defect related to a specific component. label Nov 8, 2024
@melloware melloware merged commit 9cb5e0a into primefaces:master Nov 8, 2024
4 checks passed
@KumJungMin KumJungMin deleted the fix/issue-7389 branch November 10, 2024 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Issue contains a defect related to a specific component.
Projects
None yet
2 participants