Skip to content

Commit

Permalink
Merge pull request #47 from VanshDobhal/feature/keyboard-tooltips
Browse files Browse the repository at this point in the history
Implemented tooltip system for keyboard navigation
  • Loading branch information
mrinal1224 authored Dec 23, 2024
2 parents 6fd1f21 + f384a66 commit 19a5473
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 30 deletions.
93 changes: 63 additions & 30 deletions src/components/ExcelClone.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,80 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import './Tooltip.css'; // Add tooltip styles

const ROWS = 20;
const COLS = 26; // A to Z
const Tooltip = ({ text, position }) => {
return (
<div className={`tooltip ${position}`}>
{text}
</div>
);
};

const ExcelClone = () => {
// State for cell data
const [data, setData] = useState(
Array(ROWS).fill().map(() => Array(COLS).fill(''))
);

// State for selected cell
const ROWS = 20;
const COLS = 26; // A to Z
const [data, setData] = useState(Array(ROWS).fill().map(() => Array(COLS).fill('')));
const [selectedCell, setSelectedCell] = useState(null);

// State for formula bar
const [formulaBarValue, setFormulaBarValue] = useState('');
const [tooltipText, setTooltipText] = useState(''); // State for dynamic tooltip

// Convert column index to letter (0 = A, 1 = B, etc.)
const getColumnLabel = (index) => String.fromCharCode(65 + index);

// Handle cell selection
const handleCellSelect = (rowIndex, colIndex) => {
setSelectedCell({ row: rowIndex, col: colIndex });
setFormulaBarValue(data[rowIndex][colIndex]);
};

// Handle cell value change
const handleCellChange = (rowIndex, colIndex, value) => {
const newData = [...data];
newData[rowIndex][colIndex] = value;
setData(newData);
setFormulaBarValue(value);
};

const handleKeyDown = (e) => {
const { row, col } = selectedCell || {};

if (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
setTooltipText("Use Arrow Keys to Navigate");
} else if (e.key === 'Tab') {
setTooltipText("Use Tab to Move to the Next Cell");
} else if (e.key === 'Enter') {
setTooltipText("Press Enter to Confirm");
}
};

useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [selectedCell]);

const Cell = ({ value, rowIndex, colIndex }) => {
const [showTooltip, setShowTooltip] = useState(false);

return (
<td
className={`border border-gray-300 p-0 relative ${selectedCell?.row === rowIndex && selectedCell?.col === colIndex ? 'bg-blue-50' : ''}`}
>
<div
className="cell"
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
>
<input
type="text"
className="w-full h-full px-2 py-1 border-none outline-none bg-transparent"
value={value}
onChange={(e) => handleCellChange(rowIndex, colIndex, e.target.value)}
onClick={() => handleCellSelect(rowIndex, colIndex)}
/>
{showTooltip && <Tooltip text={tooltipText} position="bottom" />}
</div>
</td>
);
};

return (
<div className="flex flex-col h-screen">
{/* Top Bar */}
Expand Down Expand Up @@ -74,22 +117,12 @@ const ExcelClone = () => {
{rowIndex + 1}
</td>
{Array(COLS).fill().map((_, colIndex) => (
<td
<Cell
key={colIndex}
className={`border border-gray-300 p-0 relative ${
selectedCell?.row === rowIndex && selectedCell?.col === colIndex
? 'bg-blue-50'
: ''
}`}
>
<input
type="text"
className="w-full h-full px-2 py-1 border-none outline-none bg-transparent"
value={data[rowIndex][colIndex]}
onChange={(e) => handleCellChange(rowIndex, colIndex, e.target.value)}
onClick={() => handleCellSelect(rowIndex, colIndex)}
/>
</td>
value={data[rowIndex][colIndex]}
rowIndex={rowIndex}
colIndex={colIndex}
/>
))}
</tr>
))}
Expand All @@ -100,4 +133,4 @@ const ExcelClone = () => {
);
};

export default ExcelClone;
export default ExcelClone;
31 changes: 31 additions & 0 deletions src/components/Tooltip.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.tooltip {
position: absolute;
background-color: rgba(0, 0, 0, 0.75);
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 12px;
pointer-events: none;
transition: opacity 0.3s ease;
}

.tooltip.bottom {
transform: translateY(100%);
top: 100%;
}

.tooltip.top {
transform: translateY(-100%);
bottom: 100%;
}

.tooltip.left {
transform: translateX(-100%);
right: 100%;
}

.tooltip.right {
transform: translateX(100%);
left: 100%;
}

24 changes: 24 additions & 0 deletions src/components/Tooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { useState, useEffect } from 'react';
import './Tooltip.css'; // Add tooltip styles

const Tooltip = ({ text, target }) => {
const [style, setStyle] = useState({});

useEffect(() => {
if (target) {
const rect = target.getBoundingClientRect();
setStyle({
top: rect.top + window.scrollY - 40, // Adjust top offset
left: rect.left + window.scrollX + rect.width / 2, // Adjust left offset
});
}
}, [target]);

return (
<div className="tooltip" style={style}>
{text}
</div>
);
};

export default Tooltip;

0 comments on commit 19a5473

Please sign in to comment.