diff --git a/frontend/code/components/progressBar.ts b/frontend/code/components/progressBar.ts
index e2dde8eb..32a8ccce 100644
--- a/frontend/code/components/progressBar.ts
+++ b/frontend/code/components/progressBar.ts
@@ -1,9 +1,12 @@
+import { ColorSet } from '../dataModels';
+import { applySwitcheroo } from '../designApplication';
import { LayoutContext } from '../layouting';
import { ComponentBase, ComponentState } from './componentBase';
export type ProgressBarState = ComponentState & {
_type_: 'ProgressBar-builtin';
progress?: number | null;
+ color?: ColorSet;
};
export class ProgressBarComponent extends ComponentBase {
@@ -11,12 +14,12 @@ export class ProgressBarComponent extends ComponentBase {
createElement(): HTMLElement {
let element = document.createElement('div');
- element.classList.add('rio-progressbar');
+ element.classList.add('rio-progress-bar');
element.innerHTML = `
-
-
-
+
`;
@@ -33,7 +36,7 @@ export class ProgressBarComponent extends ComponentBase {
// Indeterminate progress
else if (deltaState.progress === null) {
- this.element.classList.add('rio-progressbar-indeterminate');
+ this.element.classList.add('rio-progress-bar-indeterminate');
}
// Known progress
@@ -41,10 +44,18 @@ export class ProgressBarComponent extends ComponentBase {
let progress = Math.max(0, Math.min(1, deltaState.progress));
this.element.style.setProperty(
- '--rio-progressbar-fraction',
+ '--rio-progress-bar-fraction',
`${progress * 100}%`
);
- this.element.classList.remove('rio-progressbar-indeterminate');
+ this.element.classList.remove('rio-progress-bar-indeterminate');
+ }
+
+ // Apply the color
+ if (deltaState.color !== undefined) {
+ applySwitcheroo(
+ this.element,
+ deltaState.color === 'keep' ? 'bump' : deltaState.color
+ );
}
}
diff --git a/frontend/code/components/progressCircle.ts b/frontend/code/components/progressCircle.ts
index 938a8e2a..6019c7df 100644
--- a/frontend/code/components/progressCircle.ts
+++ b/frontend/code/components/progressCircle.ts
@@ -4,8 +4,8 @@ import { ComponentBase, ComponentState } from './componentBase';
export type ProgressCircleState = ComponentState & {
_type_: 'ProgressCircle-builtin';
- color: ColorSet;
progress?: number | null;
+ color?: ColorSet;
};
export class ProgressCircleComponent extends ComponentBase {
@@ -45,9 +45,11 @@ export class ProgressCircleComponent extends ComponentBase {
}
// Apply the color
- applySwitcheroo(
- this.element,
- deltaState.color === 'keep' ? 'bump' : deltaState.color
- );
+ if (deltaState.color !== undefined) {
+ applySwitcheroo(
+ this.element,
+ deltaState.color === 'keep' ? 'bump' : deltaState.color
+ );
+ }
}
}
diff --git a/frontend/css/style.scss b/frontend/css/style.scss
index df433c26..348837b0 100644
--- a/frontend/css/style.scss
+++ b/frontend/css/style.scss
@@ -549,12 +549,12 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
}
// Progress Bar
-.rio-progressbar {
+.rio-progress-bar {
pointer-events: none;
overflow: hidden;
}
-.rio-progressbar-track {
+.rio-progress-bar-track {
position: absolute;
width: 100%;
height: 100%;
@@ -563,14 +563,14 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
opacity: 0.3;
}
-.rio-progressbar-fill {
+.rio-progress-bar-fill {
position: absolute;
height: 100%;
- background: var(--rio-local-level-2-bg);
+ background: var(--rio-local-bg);
}
-@keyframes rio-progressbar-animation-indeterminate {
+@keyframes rio-progress-bar-animation-indeterminate {
0% {
left: -20%;
width: 6%;
@@ -586,14 +586,15 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
}
}
-.rio-progressbar-indeterminate .rio-progressbar-fill {
+.rio-progress-bar-indeterminate .rio-progress-bar-fill {
transform: translateX(-50%);
- animation: rio-progressbar-animation-indeterminate 1.5s ease-in-out infinite;
+ animation: rio-progress-bar-animation-indeterminate 1.5s ease-in-out
+ infinite;
}
-.rio-progressbar:not(.rio-progressbar-indeterminate) .rio-progressbar-fill {
+.rio-progress-bar:not(.rio-progress-bar-indeterminate) .rio-progress-bar-fill {
left: 0;
- width: var(--rio-progressbar-fraction);
+ width: var(--rio-progress-bar-fraction);
transition: width 0.3s ease-in-out;
}
@@ -617,7 +618,7 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label,
.rio-progress-circle circle {
fill: none;
stroke-width: 3.5;
- color: var(--rio-local-level-2-bg);
+ color: var(--rio-local-bg);
}
.spinning svg {
diff --git a/rio/cli/run_project/arbiter.py b/rio/cli/run_project/arbiter.py
index 136c5f8e..a47eaa01 100644
--- a/rio/cli/run_project/arbiter.py
+++ b/rio/cli/run_project/arbiter.py
@@ -545,13 +545,19 @@ class Arbiter:
except ValueError:
pass
else:
+ # From experience, people don't even notice the warnings in `rio
+ # run` anymore after some time, because they show up so
+ # frequently. Intentionally style this one differently, since
+ # its important and must be noticed.
if newest_rio_version != installed_rio_version:
- revel.warning(
- f"Rio [bold]{newest_rio_version}[/] is available, but"
- f" you have [bold]{installed_rio_version}[/] installed."
+ revel.print(
+ f"[bg-yellow] [/] [bold yellow]Rio [bold]{newest_rio_version}[/] is available![/]"
)
- revel.warning(
- "Run `pip install --upgrade rio-ui` to get the latest bugfixes and improvements."
+ revel.print(
+ f"[bg-yellow] [/] [bold yellow]Please update to get the newest features, bugfixes and security updates.[/]"
+ )
+ revel.print(
+ "[bg-yellow] [/] Run `[bold]pip install --upgrade rio-ui[/]` to get the newest version."
)
print()
diff --git a/rio/components/list_view.py b/rio/components/list_view.py
index 8d21232e..71c74a76 100644
--- a/rio/components/list_view.py
+++ b/rio/components/list_view.py
@@ -47,7 +47,7 @@ class ListView(FundamentalComponent):
## Examples
- A minimal example of a `ListView` with two items will be shown:
+ This example will display a list of two products:
```python
rio.ListView(
@@ -56,8 +56,9 @@ class ListView(FundamentalComponent):
)
```
- `ListView`s are commonly used to display lists of dynamic length. You can easily
- achieve this by adding the children to a list first, and then unpacking that list:
+ `ListView`s are commonly used to display lists of dynamic length. You can
+ easily achieve this by first creating a `ListView`, then adding the children
+ after the fact:
```python
import functools
@@ -70,16 +71,17 @@ class ListView(FundamentalComponent):
print(f"Selected {product}")
def build(self) -> rio.Component:
- # Store all children in an intermediate list
- list_items = []
+ # First create the ListView
+ result = rio.ListView()
+ # Then add the children one by one
for product in self.products:
- list_items.append(
+ result.add(
rio.SimpleListItem(
text=product,
key=product,
- # Note the use of `functools.partial` to pass the product
- # to the event handler.
+ # Note the use of `functools.partial` to pass the
+ # product to the event handler.
on_press=functools.partial(
self.on_press_heading_list_item,
product=product,
@@ -87,8 +89,7 @@ class ListView(FundamentalComponent):
)
)
- # Then unpack the list to pass the children to the `ListView`
- return rio.ListView(*list_items)
+ return result
```
"""
diff --git a/rio/components/progress_bar.py b/rio/components/progress_bar.py
index f0e0bdcd..1fedac82 100644
--- a/rio/components/progress_bar.py
+++ b/rio/components/progress_bar.py
@@ -1,4 +1,8 @@
-from typing import final
+from __future__ import annotations
+
+from typing import * # type: ignore
+
+import rio
from .fundamental_component import FundamentalComponent
@@ -25,10 +29,14 @@ class ProgressBar(FundamentalComponent):
`progress`: The progress to display, as a fraction from 0 to 1. If `None`,
the progress indicator will be indeterminate.
+ `color`: The color scheme of the progress indicator. Keeping the default
+ is recommended, but it may make sense to change the color in
+ case the default is hard to perceive on your background.
+
## Examples
- A minimal example displaying a progress bar that is 40% complete.
+ Here's a minimal example displaying a progress circle that is 40% complete:
```python
rio.ProgressBar(progress=0.4)
@@ -43,7 +51,54 @@ class ProgressBar(FundamentalComponent):
```
"""
- progress: float | None = None
+ progress: float | None
+ color: rio.ColorSet
+
+ def __init__(
+ self,
+ *,
+ progress: float | None = None,
+ color: rio.ColorSet = "keep",
+ key: str | None = None,
+ margin: float | None = None,
+ margin_x: float | None = None,
+ margin_y: float | None = None,
+ margin_left: float | None = None,
+ margin_top: float | None = None,
+ margin_right: float | None = None,
+ margin_bottom: float | None = None,
+ width: float | Literal["natural", "grow"] = "natural",
+ height: float | Literal["natural", "grow"] = "natural",
+ align_x: float | None = None,
+ align_y: float | None = None,
+ ):
+ """
+ ## Parameters
+
+ progress: The progress to display, as a fraction from 0 to 1. If `None`,
+ the progress indicator will be indeterminate.
+
+ color: The color scheme of the progress indicator. Keeping the default
+ is recommended, but it may make sense to change the color in case
+ the default is hard to perceive on your background.
+ """
+ super().__init__(
+ key=key,
+ margin=margin,
+ margin_x=margin_x,
+ margin_y=margin_y,
+ margin_left=margin_left,
+ margin_top=margin_top,
+ margin_right=margin_right,
+ margin_bottom=margin_bottom,
+ width=width,
+ height=height,
+ align_x=align_x,
+ align_y=align_y,
+ )
+
+ self.progress = progress
+ self.color = color
ProgressBar._unique_id = "ProgressBar-builtin"
diff --git a/rio/components/progress_circle.py b/rio/components/progress_circle.py
index b94cddcd..978047c3 100644
--- a/rio/components/progress_circle.py
+++ b/rio/components/progress_circle.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from typing import Literal, final
+from typing import * # type: ignore
import rio
@@ -40,7 +40,7 @@ class ProgressCircle(FundamentalComponent):
## Examples
- A minimal example displaying a progress circle that is 40% complete.
+ Here's a minimal example displaying a progress circle that is 40% complete:
```python
rio.ProgressCircle(progress=0.4)
diff --git a/rio/components/slideshow.py b/rio/components/slideshow.py
index f9758b81..33a6e4e4 100644
--- a/rio/components/slideshow.py
+++ b/rio/components/slideshow.py
@@ -40,7 +40,7 @@ class Slideshow(FundamentalComponent):
## Examples
- A minimal example of `Slideshow` displaying two images will be shown:
+ Here's a simple example that will continuously switch between two images:
```python
from pathlib import Path
diff --git a/rio/components/switcher.py b/rio/components/switcher.py
index 5dab7f92..709f75dd 100644
--- a/rio/components/switcher.py
+++ b/rio/components/switcher.py
@@ -22,15 +22,6 @@ class Switcher(FundamentalComponent):
`content`: The currently displayed component.
- ## Examples
-
- A minimal example of a `Switcher` will be shown:
-
- ```python
- rio.Switcher(content=rio.Text("Hello, world!"))
- ```
-
-
## Metadata
`public`: False
diff --git a/rio/components/text.py b/rio/components/text.py
index 06ff7810..a740c0b2 100644
--- a/rio/components/text.py
+++ b/rio/components/text.py
@@ -41,11 +41,26 @@ class Text(FundamentalComponent):
## Examples
- A minimal example of a `Text` will be shown:
+ Here's a minimal example for displaying text. Just pass it a string:
```python
rio.Text("Hello, world!")
```
+
+ To change the style of the text, you can pass a `TextStyle` instance:
+
+ ```python
+ rio.Text(
+ "Hello, world!",
+ style=rio.TextStyle(
+ font_size=3,
+ # Text Style has a lot of optional parameters. Have a look at its
+ # docs for all details!
+ #
+ # https://rio.dev/docs/api/textstyle
+ ),
+ )
+ ```
"""
text: str
diff --git a/rio/components/tooltip.py b/rio/components/tooltip.py
index ae8605d3..099b4204 100644
--- a/rio/components/tooltip.py
+++ b/rio/components/tooltip.py
@@ -33,7 +33,7 @@ class Tooltip(FundamentalComponent):
## Examples
- A minimal example of a `Tooltip` will be shown:
+ This example will display a label for an icon when the user hovers over it:
```python
rio.Tooltip(
@@ -42,6 +42,10 @@ class Tooltip(FundamentalComponent):
position="top",
)
```
+
+ ## Metadata
+
+ `experimental`: True
"""
anchor: rio.Component
diff --git a/rio/components/website.py b/rio/components/website.py
index edbd9c2c..462e0bbd 100644
--- a/rio/components/website.py
+++ b/rio/components/website.py
@@ -24,7 +24,7 @@ class Website(FundamentalComponent):
## Examples
- A minimal example of a `Website` will be shown:
+ Here's a simple example that will display an example website:
```python
rio.Website(
diff --git a/rio/snippets/snippet-files/howtos/deployment.md b/rio/snippets/snippet-files/howtos/deployment.md
index 1cc54970..615e2acb 100644
--- a/rio/snippets/snippet-files/howtos/deployment.md
+++ b/rio/snippets/snippet-files/howtos/deployment.md
@@ -6,6 +6,7 @@ needs.
- One-click deployment (coming soon)
- Manual deployment using `rio`
- Manual deployment using `uvicorn`
+- running the app directly from Python
- Deployment inside a Docker container
## One-click deployment
@@ -35,8 +36,13 @@ Make sure **not** to pass the `--public` flag. We want to make sure Rio is only
available on your local machine.
**Alternatively**, you can run your app via a server such as `uvicorn`. At its
-core, Rio is a `fastapi` app, which means you can follow [FastAPI's deployment
-guide](https://fastapi.tiangolo.com/deployment/).
+core, Rio is a `fastapi` app and you can get the FastAPI object by calling
+`App.as_fastapi`. Then follow [FastAPI's deployment
+guide](https://fastapi.tiangolo.com/deployment/) to host your app.
+
+**Another alternative** is to run your app directly from Python. Apps have a
+`App.run_as_web_server` method, which will block and serve your app. Make sure
+to configure a port so that it doesn't run on a random one each time!
**Use Nginx as a reverse proxy**. Nginx is a powerful web server that is
hardened against attacks and safe to run on the internet. This will be what your