Repository: marimo-team/marimo
Pull request: fix: Sticky hourglass loading indicator
## 📝 Summary

Fixes #4744.

## 🔍 Description of Changes

- Use `absolute` when `viewState.mode === "edit"` and `fixed` otherwise.
- Adjusted top / left positions and left margin for run and edit mode.
- Added a test notebook to the smoke tests directory.

## 📋 Checklist

- [x] I have read the [contributor guidelines](https://github.com/marimo-team/marimo/blob/main/CONTRIBUTING.md).
- [x] For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on [Discord](https://marimo.io/discord?ref=pr), or the community [discussions](https://github.com/marimo-team/marimo/discussions) (Please provide a link if applicable).
- [x] I have added tests for the changes made.
- [x] I have run the code and verified that it works as expected.

## 📜 Reviewers

@mscolnick


Problem statement:
Loading app indicator (hourglass) doesn't scroll with page in run mode
### Describe the bug

The loading indicator (hourglass) scrolls with the page (always in viewport) in edit mode, but not in run mode. This makes it hard to know when a notebook is computing in run mode.

(@antgoldbloom)

### Environment

<details>

```
0.13.2
```

</details>


### Code to reproduce

_No response_

Hints from issue discussion:
A change fixed this for the app preview in edit mode, but this still doesn't work when running under `marimo run`. Reported by @antgoldbloom

Repro: marimo run the following

```python
import marimo

__generated_with = "0.13.11"
app = marimo.App()


@app.cell
def _():
    import marimo as mo
    return (mo,)


@app.cell
def _(mo):
    mo.md("hello world" * 10000)
    return


@app.cell
def _():
    import time; time.sleep(100)
    return


if __name__ == "__main__":
    app.run()
```

Commit message: fix: Sticky hourglass loading indicator

Patch to review:
diff --git a/frontend/src/components/editor/header/status.tsx b/frontend/src/components/editor/header/status.tsx
index 650c8bb2701..a7af63dffe4 100644
--- a/frontend/src/components/editor/header/status.tsx
+++ b/frontend/src/components/editor/header/status.tsx
@@ -24,7 +24,7 @@ export const StatusOverlay: React.FC<{
 };
 
 const topLeftStatus =
-  "absolute top-4 left-4 m-0 flex items-center space-x-3 min-h-[28px] no-print pointer-events-auto z-50 hover:cursor-pointer";
+  "fixed top-8 left-8 ml-4 flex items-center space-x-3 min-h-[28px] no-print pointer-events-auto z-50 hover:cursor-pointer";
 
 const DisconnectedIcon = () => (
   <Tooltip content="App disconnected">
diff --git a/marimo/_smoke_tests/issues/4744-fixed-loading-indicator.py b/marimo/_smoke_tests/issues/4744-fixed-loading-indicator.py
new file mode 100644
index 00000000000..fad7a8d693b
--- /dev/null
+++ b/marimo/_smoke_tests/issues/4744-fixed-loading-indicator.py
@@ -0,0 +1,34 @@
+import marimo
+
+__generated_with = "0.13.11"
+app = marimo.App()
+
+
+@app.cell
+def _():
+    import marimo as mo
+    return (mo,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+    mo.md(r"""When viewing this notebook in run mode, the hourglass loading indicator should be stickied to the top left even when scrolling down.""")
+    return
+
+
+@app.cell
+def _(mo):
+    mo.md("hello world" * 10000)
+    return
+
+
+@app.cell
+def _():
+    import time
+
+    time.sleep(100)
+    return
+
+
+if __name__ == "__main__":
+    app.run()


Code review comments:
diff_hunk: @@ -24,7 +24,7 @@ export const StatusOverlay: React.FC<{
 };
 
 const topLeftStatus =
-  "absolute top-4 left-4 m-0 flex items-center space-x-3 min-h-[28px] no-print pointer-events-auto z-50 hover:cursor-pointer";
+  "fixed top-8 left-8 ml-4 flex items-center space-x-3 min-h-[28px] no-print pointer-events-auto z-50 hover:cursor-pointer";
path: frontend/src/components/editor/header/status.tsx
text: @user1:
Does this work when the sidebar is open?

@user2:
Scoping "fixed" to just run mode might be a good call. In edit mode this already works, even in app view

@author:
> Does this work when the sidebar is open?

Oof. 🤦‍♂️ I completely forgot to check this. I'll conditionally apply the fixed style for run mode.