Dropdown causing vertical overflow in table.

As from the image I shared you can see a table that holds few data, and one of them is status selection. I created dropdown for that. But on opening that it is not overlapping the table. Instead it creates a vertical scroll bar and empty space in the bottom.
No description
3 Replies
ahmd shajmeer
ahmd shajmeerOP2mo ago
Dropdown code
const renderStatusDropdown = (record: AttendanceRecord) => {
const { id, status } = record;

const getStatusColor = (status: string) => {
switch (status) {
case "Present":
return "bg-green-100 text-green-800";
case "Absent":
return "bg-red-100 text-red-800";
case "Early Left":
return "bg-yellow-100 text-yellow-800";
default:
return "bg-gray-100 text-gray-800";
}
};

return (
<div className="relative inline-block w-full">
<div
className={`flex items-center justify-between px-3 py-1 rounded-md cursor-pointer ${getStatusColor(status)}`}
onClick={() => toggleDropdown(id)}
>
<span className="text-sm">{status}</span>
<GoTriangleDown className="ml-2" />
</div>

{/* Dropdown absolutely positioned over other rows */}
{openDropdownId === id && (
<div className="absolute left-0 mt-1 w-36 bg-white border border-gray-200 rounded-md shadow-lg z-50">
{["Present", "Absent", "Early Left"].map((statusOption) => (
<button
key={statusOption}
className={`block w-full text-left px-4 py-2 text-sm hover:bg-gray-100 rounded-none ${
status === statusOption ? getStatusColor(statusOption) : ""
}`}
onClick={() => updateStatus(id, statusOption as "Present" | "Absent" | "Early Left")}
>
{statusOption}
</button>
))}
</div>
)}
</div>
);
};
const renderStatusDropdown = (record: AttendanceRecord) => {
const { id, status } = record;

const getStatusColor = (status: string) => {
switch (status) {
case "Present":
return "bg-green-100 text-green-800";
case "Absent":
return "bg-red-100 text-red-800";
case "Early Left":
return "bg-yellow-100 text-yellow-800";
default:
return "bg-gray-100 text-gray-800";
}
};

return (
<div className="relative inline-block w-full">
<div
className={`flex items-center justify-between px-3 py-1 rounded-md cursor-pointer ${getStatusColor(status)}`}
onClick={() => toggleDropdown(id)}
>
<span className="text-sm">{status}</span>
<GoTriangleDown className="ml-2" />
</div>

{/* Dropdown absolutely positioned over other rows */}
{openDropdownId === id && (
<div className="absolute left-0 mt-1 w-36 bg-white border border-gray-200 rounded-md shadow-lg z-50">
{["Present", "Absent", "Early Left"].map((statusOption) => (
<button
key={statusOption}
className={`block w-full text-left px-4 py-2 text-sm hover:bg-gray-100 rounded-none ${
status === statusOption ? getStatusColor(statusOption) : ""
}`}
onClick={() => updateStatus(id, statusOption as "Present" | "Absent" | "Early Left")}
>
{statusOption}
</button>
))}
</div>
)}
</div>
);
};
Table Code
{!isLoading && (
<div className="bg-white rounded-lg shadow-sm overflow-hidden mb-6">
{attendanceRecords.length === 0 ? (
<div className="text-center py-8 bg-gray-50">
<p className="text-gray-500">
{selectedBatch && syllabusTopic
? "No students found for the selected filters"
: "Please select batch and syllabus topic to load students"}
</p>
</div>
) : (
<div className="overflow-x-auto overflow-y-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50 sticky top-0 z-10">
<tr>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Student Name</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Class Name</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Status</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Hours Attended</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Completed Class</th>
</tr>
</thead>
{!isLoading && (
<div className="bg-white rounded-lg shadow-sm overflow-hidden mb-6">
{attendanceRecords.length === 0 ? (
<div className="text-center py-8 bg-gray-50">
<p className="text-gray-500">
{selectedBatch && syllabusTopic
? "No students found for the selected filters"
: "Please select batch and syllabus topic to load students"}
</p>
</div>
) : (
<div className="overflow-x-auto overflow-y-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50 sticky top-0 z-10">
<tr>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Student Name</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Class Name</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Status</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Hours Attended</th>
<th className="px-6 py-3 text-left text-sm font-medium text-gray-900">Completed Class</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{attendanceRecords.map((record) => (
<tr key={record.id}>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{record.studentName}</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{record.courseName}</td>
<td className="align-top px-6 py-4 whitespace-nowrap text-sm">{renderStatusDropdown(record)}</td>
<td className="px-6 py-4 whitespace-nowrap text-sm">
<input
type="number"
value={record.hoursAttended}
onChange={(e) => updateHours(record.id, parseInt(e.target.value) || 0)}
className="w-20 px-2 py-1 border border-gray-300 rounded text-center focus:outline-none focus:ring-2 focus:ring-blue-200"
min="0"
max="24"
/>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm">
<div className="flex items-center">
<input
type="checkbox"
checked={record.completedClass}
onChange={(e) => updateCompletedClass(record.id, e.target.checked)}
className="size-6 accent-[#e4fbb1] rounded focus:ring-2 focus:ring-[#e4fbb1]"
/>
<span className="ml-2 text-gray-600">
{record.completedClass ? "Yes" : "No"}
</span>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
)}
<tbody className="bg-white divide-y divide-gray-200">
{attendanceRecords.map((record) => (
<tr key={record.id}>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{record.studentName}</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{record.courseName}</td>
<td className="align-top px-6 py-4 whitespace-nowrap text-sm">{renderStatusDropdown(record)}</td>
<td className="px-6 py-4 whitespace-nowrap text-sm">
<input
type="number"
value={record.hoursAttended}
onChange={(e) => updateHours(record.id, parseInt(e.target.value) || 0)}
className="w-20 px-2 py-1 border border-gray-300 rounded text-center focus:outline-none focus:ring-2 focus:ring-blue-200"
min="0"
max="24"
/>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm">
<div className="flex items-center">
<input
type="checkbox"
checked={record.completedClass}
onChange={(e) => updateCompletedClass(record.id, e.target.checked)}
className="size-6 accent-[#e4fbb1] rounded focus:ring-2 focus:ring-[#e4fbb1]"
/>
<span className="ml-2 text-gray-600">
{record.completedClass ? "Yes" : "No"}
</span>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
)}
https://codesandbox.io/p/sandbox/nifty-ishizaka-ym8fy6
ἔρως
ἔρως2mo ago
this must have position absolute otherwise it stays in the flow of the document oh, wait, you have it with position absolute 🤔 well, i tested it on my phone, and, before it crashed, it was working fine
Mannix
Mannix2mo ago
the cause it the use of the overflow classes

Did you find this page helpful?