Skip to content

Commit 25c4bbf

Browse files
authored
Use transform scaleX for progress bar animation
1 parent 772d88a commit 25c4bbf

4 files changed

Lines changed: 20 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# Changelog
22

33
Please see [our GitHub "Releases" page](https://github.com/hotwired/turbo/releases).
4+
5+
Unreleased note: `.turbo-progress-bar` now renders at full width and uses `transform: scaleX(...)` for progress animation. Custom overrides that animate or read `width` should migrate to `transform`.

src/core/drive/progress_bar.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ export class ProgressBar {
1010
display: block;
1111
top: 0;
1212
left: 0;
13+
width: 100%;
1314
height: 3px;
1415
background: #0076ff;
1516
z-index: 2147483647;
17+
transform-origin: 0 0;
18+
transform: scaleX(0) translateZ(0);
1619
transition:
17-
width ${ProgressBar.animationDuration}ms ease-out,
20+
transform ${ProgressBar.animationDuration}ms ease-out,
1821
opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in;
19-
transform: translate3d(0, 0, 0);
22+
will-change: transform, opacity;
2023
}
2124
`
2225
}
@@ -68,7 +71,7 @@ export class ProgressBar {
6871
}
6972

7073
installProgressElement() {
71-
this.progressElement.style.width = "0"
74+
this.progressElement.style.transform = "scaleX(0) translateZ(0)"
7275
this.progressElement.style.opacity = "1"
7376
document.documentElement.insertBefore(this.progressElement, document.body)
7477
this.refresh()
@@ -102,7 +105,8 @@ export class ProgressBar {
102105

103106
refresh() {
104107
requestAnimationFrame(() => {
105-
this.progressElement.style.width = `${10 + this.value * 90}%`
108+
const scale = (10 + this.value * 90) / 100
109+
this.progressElement.style.transform = `scaleX(${scale}) translateZ(0)`
106110
})
107111
}
108112

src/tests/functional/form_submission_tests.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ test("test standard form submission renders a progress bar", async ({ page }) =>
3838

3939
await waitUntilSelector(page, ".turbo-progress-bar")
4040
assert.ok(await hasSelector(page, ".turbo-progress-bar"), "displays progress bar")
41+
assert.match(
42+
await page.locator(".turbo-progress-bar").evaluate((element) => (element as HTMLDivElement).style.transform),
43+
/^scaleX\(.+\) translateZ\(0(px)?\)$/,
44+
"animates progress with transform"
45+
)
4146

4247
await nextBody(page)
4348
await waitUntilNoSelector(page, ".turbo-progress-bar")

src/tests/functional/navigation_tests.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ test("test navigating renders a progress bar", async ({ page }) => {
3838

3939
await waitUntilSelector(page, ".turbo-progress-bar")
4040
assert.ok(await hasSelector(page, ".turbo-progress-bar"), "displays progress bar")
41+
assert.match(
42+
await page.locator(".turbo-progress-bar").evaluate((element) => (element as HTMLDivElement).style.transform),
43+
/^scaleX\(.+\) translateZ\(0(px)?\)$/,
44+
"animates progress with transform"
45+
)
4146

4247
await nextEventNamed(page, "turbo:load")
4348
await waitUntilNoSelector(page, ".turbo-progress-bar")

0 commit comments

Comments
 (0)