progressbars now have a color & improved documentation

This commit is contained in:
Jakob Pinterits
2024-05-24 08:17:44 +02:00
parent c03be249cc
commit bbb9d5c381
13 changed files with 149 additions and 57 deletions

View File

@@ -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 = `
<div class="rio-progressbar-inner">
<div class="rio-progressbar-track"></div>
<div class="rio-progressbar-fill"></div>
<div class="rio-progress-bar-inner">
<div class="rio-progress-bar-track"></div>
<div class="rio-progress-bar-fill"></div>
</div>
`;
@@ -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
);
}
}

View File

@@ -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
);
}
}
}

View File

@@ -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 {

View File

@@ -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()

View File

@@ -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
```
"""

View File

@@ -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"

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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