Skip to content

Commit 44bc4fe

Browse files
authored
fix(Calendar): race condition in month navigation (#1686)
1 parent 1dc8add commit 44bc4fe

File tree

4 files changed

+22
-20
lines changed

4 files changed

+22
-20
lines changed

.changeset/deep-clubs-brake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"bits-ui": patch
3+
---
4+
5+
fix(Calendar): resolve race condition in month navigation

.github/workflows/ci.yml

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,8 @@ jobs:
7272
- run: pnpm test:utils
7373

7474
Test:
75-
name: Test - ${{ matrix.browser }}
75+
name: Test - Chromium
7676
runs-on: macos-latest
77-
strategy:
78-
matrix:
79-
browser: [chromium, firefox, webkit]
8077
steps:
8178
- uses: actions/checkout@v4
8279
- uses: pnpm/action-setup@v4
@@ -88,15 +85,10 @@ jobs:
8885
run: pnpm install --frozen-lockfile
8986

9087
- name: Install Playwright browser
91-
run: pnpm dlx playwright install ${{ matrix.browser }}
88+
run: pnpm dlx playwright install chromium
9289

9390
- name: Build packages
9491
run: pnpm build:packages
9592

9693
- name: Run browser tests
97-
run: |
98-
if [ "${{ matrix.browser }}" = "firefox" ]; then
99-
rm -rf tests/node_modules/.vite && pnpm test:browser --browser ${{ matrix.browser }} --no-file-parallelism
100-
else
101-
rm -rf tests/node_modules/.vite && pnpm test:browser --browser ${{ matrix.browser }}
102-
fi
94+
run: pnpm test:browser:chromium

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"lint:fix": "eslint --fix .",
1414
"test": "pnpm -F \"./{packages,tests}/**\" --parallel --reporter append-only --color test",
1515
"test:browser": "pnpm -F tests test:browser",
16+
"test:browser:chromium": "pnpm -F tests test:browser --browser chromium",
1617
"test:components": "pnpm -F tests test",
1718
"test:utils": "pnpm -F bits-ui test"
1819
},

packages/bits-ui/src/lib/internal/date-time/calendar-helpers.svelte.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,18 +440,20 @@ export function handleCalendarNextPage({
440440
if (pagedNavigation) {
441441
setPlaceholder(firstMonth.add({ months: numberOfMonths }));
442442
} else {
443+
// Calculate the target date first, then update both months and placeholder
444+
// to ensure they're synchronized and prevent useMonthViewPlaceholderSync from
445+
// double-triggering
446+
const targetDate = firstMonth.add({ months: 1 });
443447
const newMonths = createMonths({
444-
dateObj: firstMonth.add({ months: 1 }),
448+
dateObj: targetDate,
445449
weekStartsOn,
446450
locale,
447451
fixedWeeks,
448452
numberOfMonths,
449453
});
450-
setMonths(newMonths);
451454

452-
const firstNewMonth = newMonths[0];
453-
if (!firstNewMonth) return;
454-
setPlaceholder(firstNewMonth.value.set({ day: 1 }));
455+
setPlaceholder(targetDate);
456+
setMonths(newMonths);
455457
}
456458
}
457459

@@ -470,18 +472,20 @@ export function handleCalendarPrevPage({
470472
if (pagedNavigation) {
471473
setPlaceholder(firstMonth.subtract({ months: numberOfMonths }));
472474
} else {
475+
// Calculate the target date first, then update both months and placeholder
476+
// to ensure they're synchronized and prevent useMonthViewPlaceholderSync from
477+
// double-triggering
478+
const targetDate = firstMonth.subtract({ months: 1 });
473479
const newMonths = createMonths({
474-
dateObj: firstMonth.subtract({ months: 1 }),
480+
dateObj: targetDate,
475481
weekStartsOn,
476482
locale,
477483
fixedWeeks,
478484
numberOfMonths,
479485
});
480486

487+
setPlaceholder(targetDate);
481488
setMonths(newMonths);
482-
const firstNewMonth = newMonths[0];
483-
if (!firstNewMonth) return;
484-
setPlaceholder(firstNewMonth.value.set({ day: 1 }));
485489
}
486490
}
487491

0 commit comments

Comments
 (0)