Skip to content

Commit ec9bcb4

Browse files
Copilothotlong
andcommitted
fix: widen dialog on large screens (sm:max-w-3xl lg:max-w-5xl), fix React #185 close-reset cycle by separating useEffect
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent b989011 commit ec9bcb4

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- **Page Jump Input**: New input field in pagination bar allows users to type a page number and press Enter to jump directly to any page.
1717
- **Enhanced Search Bar**: Redesigned with a subtle background container and borderless input for a cleaner, more modern appearance.
1818
- **Improved Table Styling**: Even/odd row striping (`bg-muted/20`), refined selected-row highlighting (`bg-primary/5`), uppercase column headers with tighter tracking, rounded table border, and improved cell padding.
19-
- **Responsive Dialog**: Widened dialog from `max-w-2xl` to `max-w-3xl` for better data density on larger screens; filter panel supports 3-column layout on wide viewports (`lg:grid-cols-3`).
19+
- **Responsive Dialog**: Responsive dialog sizing from `sm:max-w-3xl` to `lg:max-w-5xl` for optimal data density across screen sizes; filter panel supports 3-column layout on wide viewports (`lg:grid-cols-3`).
20+
- **Fixed Close-Reset Cycle**: Separated dialog close-reset logic into its own `useEffect` (depends only on `open`) to prevent cascading state updates that could trigger React Error #185 (Maximum update depth exceeded) when selecting a record.
2021
- **8 New Unit Tests**: Comprehensive test coverage for skeleton loading (column count validation), sticky header classes, page jump navigation (valid/invalid/single-page), and loading overlay behavior.
2122

2223
- **"Browse All" Button for Lookup Fields** (`@object-ui/fields`): Added an always-visible "Browse All" (table icon) button next to the Lookup quick-select trigger. Opens the full RecordPickerDialog directly, regardless of record count — making enterprise features (multi-column table, sort/filter bar, cell renderers) discoverable at all times. Previously, the dialog was only accessible via the "Show All Results" in-popover button, which only appeared when total records exceeded the page size. The button uses accessible `aria-label`, `title`, and Lucide `TableProperties` icon. Keyboard and screen reader accessible.

packages/fields/src/widgets/RecordPickerDialog.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -460,13 +460,11 @@ export function RecordPickerDialog({
460460
[sortField, sortDirection],
461461
);
462462

463-
// Fetch when dialog opens, page changes, sort changes, or filters change
463+
// Reset state when dialog closes — separate from the fetch effect so that
464+
// resetting currentPage / sortField (which are fetch-effect deps) does not
465+
// re-trigger the fetch effect and cause cascading re-renders (React #185).
464466
useEffect(() => {
465-
if (open) {
466-
fetchRecords(searchQuery || undefined, currentPage, currentSort);
467-
}
468467
if (!open) {
469-
// Reset state on close
470468
setSearchQuery('');
471469
setCurrentPage(1);
472470
setError(null);
@@ -478,11 +476,23 @@ export function RecordPickerDialog({
478476
setFilterValues({});
479477
setColumnWidths({});
480478
setPageJumpValue('');
481-
// Reset pending selection to match current value
482479
setPendingSelection(new Set(
483480
multiple ? (Array.isArray(value) ? value : []) : [],
484481
));
485482
}
483+
// Intentionally depends only on `open` — `multiple` and `value` are
484+
// captured at close-time and don't need to trigger resets while closed.
485+
// eslint-disable-next-line react-hooks/exhaustive-deps
486+
}, [open]);
487+
488+
// Fetch when dialog is open and pagination / sort / filter deps change
489+
useEffect(() => {
490+
if (open) {
491+
fetchRecords(searchQuery || undefined, currentPage, currentSort);
492+
}
493+
// `fetchRecords` and `searchQuery` are intentionally excluded:
494+
// fetchRecords is stable (useCallback), searchQuery triggers its own
495+
// debounced fetch in handleSearchChange.
486496
// eslint-disable-next-line react-hooks/exhaustive-deps
487497
}, [open, currentPage, currentSort, mergedFilter]);
488498

@@ -813,7 +823,7 @@ export function RecordPickerDialog({
813823
return (
814824
<Dialog open={open} onOpenChange={onOpenChange}>
815825
<DialogContent
816-
className="max-w-3xl w-[95vw] sm:w-full max-h-[85vh] sm:max-h-[80vh] flex flex-col gap-0"
826+
className="w-[95vw] sm:max-w-3xl lg:max-w-5xl max-h-[85vh] sm:max-h-[80vh] flex flex-col gap-0"
817827
data-testid="record-picker-dialog"
818828
>
819829
<DialogHeader>

0 commit comments

Comments
 (0)