mirror of
https://github.com/rio-labs/rio.git
synced 2026-01-06 05:09:43 -06:00
progressbars now have a color & improved documentation
This commit is contained in:
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user