Skip to content

Fix: Responsive UI changes #33

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

Merged
merged 3 commits into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 72 additions & 5 deletions example/src/styles/RowDetailsPopup.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -23,8 +22,10 @@
max-width: 500px;
width: 90%;
max-height: 80vh;
overflow: hidden;
overflow: hidden; /* Changed to hidden to prevent overall scroll */
font-family: 'DM Sans', sans-serif;
display: flex;
flex-direction: column;
}

.row-details-popup-header {
Expand All @@ -33,6 +34,7 @@
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0; /* Prevent header from shrinking */
}

.row-details-popup-title {
Expand All @@ -55,8 +57,9 @@

.row-details-popup-content {
padding: 1.5rem;
max-height: 60vh;
overflow-y: auto;
flex: 1; /* Take remaining space */
overflow-y: auto; /* Enable scroll only for content */
min-height: 0; /* Allow content to shrink */
}

.row-details-popup-footer {
Expand All @@ -65,6 +68,7 @@
display: flex;
justify-content: flex-end;
gap: 0.75rem;
flex-shrink: 0; /* Prevent footer from shrinking */
}

.row-details-popup-close-action {
Expand Down Expand Up @@ -180,5 +184,68 @@

/* Disable background scroll when popup is open */
body.popup-open {
overflow: hidden;
overflow: hidden !important;
position: fixed !important;
width: 100% !important;
height: 100% !important;
}

/* Prevent scrolling on all table containers when popup is open */
body.popup-open .table-wrapper,
body.popup-open .table-container,
body.popup-open .app-content,
body.popup-open .app {
overflow: hidden !important;
pointer-events: none !important;
}

/* Override the table's !important overflow rules when popup is open */
body.popup-open .table-responsive-container {
overflow: hidden !important;
overflow-x: hidden !important;
overflow-y: hidden !important;
pointer-events: none !important;
}

/* Override all media query rules for table scrolling when popup is open */
body.popup-open .table-responsive-container,
body.popup-open .table-responsive-container::-webkit-scrollbar {
overflow: hidden !important;
overflow-x: hidden !important;
overflow-y: hidden !important;
pointer-events: none !important;
}

/* Override the specific media query rules that use !important */
@media (max-width: 1199px) {
body.popup-open .table-responsive-container {
overflow: hidden !important;
overflow-x: hidden !important;
overflow-y: hidden !important;
pointer-events: none !important;
}
}

@media (max-width: 768px) {
body.popup-open .table-responsive-container {
overflow: hidden !important;
overflow-x: hidden !important;
overflow-y: hidden !important;
pointer-events: none !important;
}
}

@media (max-width: 480px) {
body.popup-open .table-responsive-container {
overflow: hidden !important;
overflow-x: hidden !important;
overflow-y: hidden !important;
pointer-events: none !important;
}
}

/* Allow scrolling only within the popup */
body.popup-open .row-details-popup-overlay,
body.popup-open .row-details-popup {
pointer-events: auto !important;
}
4 changes: 2 additions & 2 deletions src/components/ButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ export const ButtonGroup: React.FC<ButtonGroupProps> = ({
};

return (
<div style={{ display: "flex", gap: "0.5rem", flexShrink: 0 }}>
<div style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap", alignItems: "center" }}>
{buttons.map((button) => (
<div key={button.id} style={{ position: 'relative' }}>
<div key={button.id} style={{ position: 'relative', flexShrink: 0 }}>
<Button
icon={button.icon}
text={button.text}
Expand Down
68 changes: 33 additions & 35 deletions src/components/MultiLevelTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -704,43 +704,41 @@ export const MultiLevelTable: React.FC<MultiLevelTableProps> = ({
<div className="table-wrapper">
{showSearchBar && (
<div className="search-bar-container">
<div className="search-bar-left">
{tableTitle && (
<div className="table-title-container">
<h2 style={componentStyles.title.table}>
{tableTitle}
</h2>
{tableSubtitle && (
<p
className="table-subtitle"
style={{
color: mergedTheme.colors?.textColor || colors.textSecondary,
}}
>
{tableSubtitle}
</p>
)}
</div>
)}
<div className="search-input-container">
<span className="search-input-icon">
<SearchIcon width={24} height={24} />
</span>
<input
className="search-input"
type="text"
placeholder="Search"
value={searchTerm}
onChange={e => onSearchChange?.(e.target.value)}
style={{
borderColor: mergedTheme.table?.cell?.borderColor || colors.searchBorder,
backgroundColor: mergedTheme.colors?.background || colors.backgroundWhite,
color: mergedTheme.colors?.textColor || colors.textPrimary,
}}
/>
{tableTitle && (
<div className="table-title-container">
<h2 style={componentStyles.title.table}>
{tableTitle}
</h2>
{tableSubtitle && (
<p
className="table-subtitle"
style={{
color: mergedTheme.colors?.textColor || colors.textSecondary,
}}
>
{tableSubtitle}
</p>
)}
</div>
)}
<div className="search-input-container">
<span className="search-input-icon">
<SearchIcon width={24} height={24} />
</span>
<input
className="search-input"
type="text"
placeholder="Search"
value={searchTerm}
onChange={e => onSearchChange?.(e.target.value)}
style={{
borderColor: mergedTheme.table?.cell?.borderColor || colors.searchBorder,
backgroundColor: mergedTheme.colors?.background || colors.backgroundWhite,
color: mergedTheme.colors?.textColor || colors.textPrimary,
}}
/>
</div>
<div className="search-bar-right">
<div className="action-buttons-container">
{renderActionButtons()}
</div>
</div>
Expand Down
89 changes: 71 additions & 18 deletions src/components/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';

import { ArrowIcon } from './icons';
import { PAGE_SIZE_OPTIONS } from '../constants/pagination';
Expand Down Expand Up @@ -55,40 +55,90 @@ export const Pagination: React.FC<PaginationProps> = ({
setPageSize,
totalItems
}) => {
// Generate page numbers to show
// Track screen width for responsive pagination
const [screenWidth, setScreenWidth] = useState(window.innerWidth);

// Update screen width on window resize
useEffect(() => {
const handleResize = () => {
setScreenWidth(window.innerWidth);
};

window.addEventListener('resize', handleResize);

// Cleanup event listener on component unmount
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);

// Generate page numbers to show based on screen size
const getVisiblePages = () => {
const pages: number[] = [];

// If 5 or fewer pages, show all
if (pageCount <= 5) {
// Determine how many page numbers to show based on screen width
let maxVisiblePages: number;
let showPageNumbers = true;

if (screenWidth <= 374)
// Very small screens: show only 2 page numbers + ellipsis
maxVisiblePages = 2;
else if (screenWidth <= 542)
// Small screens: show 3 page numbers + ellipsis
maxVisiblePages = 3;
else if (screenWidth < 1228)
// Medium screens: show 4 page numbers + ellipsis
maxVisiblePages = 4;
else
// Large screens: show up to 6 page numbers
maxVisiblePages = 6;

// For very small screens, don't show page numbers at all
if (screenWidth <= 415)
showPageNumbers = false;

// If not showing page numbers, return empty array (only arrows will show)
if (!showPageNumbers)
return pages;

// If total pages is less than or equal to max visible pages, show all
if (pageCount <= maxVisiblePages) {
for (let i = 0; i < pageCount; i++)
pages.push(i);

return pages;
}

// For more than 5 pages, show smart pagination
if (pageIndex <= 2) {
// Near start: show 1, 2, 3, 4, 5, ..., last
for (let i = 0; i < 5; i++)
// Calculate how many pages to show on each side of current page
const sidePages = Math.floor((maxVisiblePages - 1) / 2);

// Near start
if (pageIndex <= sidePages) {
// Show first few pages + ellipsis + last page
for (let i = 0; i < maxVisiblePages - 1; i++)
pages.push(i);

pages.push(-1); // Ellipsis marker
pages.push(pageCount - 1);
} else if (pageIndex >= pageCount - 3) {
// Near end: show 1, ..., last-4, last-3, last-2, last-1, last
}
// Near end
else if (pageIndex >= pageCount - sidePages - 1) {
// Show first page + ellipsis + last few pages
pages.push(0);
pages.push(-1); // Ellipsis marker
for (let i = pageCount - 5; i < pageCount; i++)
pages.push(i);

} else {
// Middle: show 1, ..., current-1, current, current+1, ..., last
for (let i = pageCount - (maxVisiblePages - 1); i < pageCount; i++)
pages.push(i);
}
// Middle
else {
// Show first page + ellipsis + current and neighbors + ellipsis + last page
pages.push(0);
pages.push(-1); // Ellipsis marker
pages.push(pageIndex - 1);
pages.push(pageIndex);
pages.push(pageIndex + 1);

for (let i = pageIndex - sidePages; i <= pageIndex + sidePages; i++)
pages.push(i);

pages.push(-1); // Ellipsis marker
pages.push(pageCount - 1);
}
Expand All @@ -108,7 +158,10 @@ export const Pagination: React.FC<PaginationProps> = ({
position: 'absolute'
}}>
{/* Total Items Text */}
<div style={{ ...componentStyles.pagination.totalItems, position: 'static' }}>
<div
className="pagination-total-items"
style={{ ...componentStyles.pagination.totalItems, position: 'static' }}
>
Total {totalItems} items
</div>

Expand Down
Loading
Loading