Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/databasedav/haalka
ergonomic reactive Bevy UI library powered by FRP signals
https://github.com/databasedav/haalka
bevy framework frp reactive rust signals ui
Last synced: 7 days ago
JSON representation
ergonomic reactive Bevy UI library powered by FRP signals
- Host: GitHub
- URL: https://github.com/databasedav/haalka
- Owner: databasedav
- License: apache-2.0
- Created: 2023-12-26T09:40:39.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-01-14T09:51:31.000Z (10 days ago)
- Last Synced: 2025-01-14T18:09:37.604Z (10 days ago)
- Topics: bevy, framework, frp, reactive, rust, signals, ui
- Language: Rust
- Homepage:
- Size: 711 MB
- Stars: 110
- Watchers: 3
- Forks: 3
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# haalka [হালকা](https://translate.google.com/?sl=bn&tl=en&text=%E0%A6%B9%E0%A6%BE%E0%A6%B2%E0%A6%95%E0%A6%BE&op=translate)
[![Crates.io Version](https://img.shields.io/crates/v/haalka?style=for-the-badge)](https://crates.io/crates/haalka)
[![Docs.rs](https://img.shields.io/docsrs/haalka?style=for-the-badge)](https://docs.rs/haalka)```text
in bengali, haalka means "light" (e.g. not heavy) and can also be used to mean "easy"
```[haalka](https://github.com/databasedav/haalka) is an ergonomic reactive [Bevy](https://github.com/bevyengine/bevy) UI library powered by the incredible [FRP](https://en.wikipedia.org/wiki/Functional_reactive_programming) signals of [futures-signals](https://github.com/Pauan/rust-signals) and the convenient async ECS of [bevy-async-ecs](https://github.com/dlom/bevy-async-ecs) with API ported from web UI libraries [MoonZoon](https://github.com/MoonZoon/MoonZoon) and [Dominator](https://github.com/Pauan/rust-dominator).
While haalka is primarily targeted at UI and provides high level UI abstractions as such, its [core abstraction](https://docs.rs/haalka/latest/haalka/struct.RawHaalkaEl.html) can be used to manage signals-powered reactivity for any entity, not just [bevy_ui nodes](https://github.com/bevyengine/bevy/blob/main/crates/bevy_ui/src/node_bundles.rs).
## considerations
If one is using the `text_input` feature (enabled by default) and using multiple cameras in the same world, they must enable the `multicam` feature AND add the `bevy_cosmic_edit::CosmicPrimaryCamera` marker component to the primary camera.## [feature flags](https://docs.rs/haalka/latest/haalka/#feature-flags-1)
## examples
```rust no_run
use bevy::prelude::*;
use haalka::prelude::*;fn main() {
App::new()
.add_plugins((DefaultPlugins, HaalkaPlugin))
.add_systems(
Startup,
(
|world: &mut World| {
ui_root().spawn(world);
},
camera,
),
)
.run();
}#[derive(Component)]
struct Counter(Mutable);fn ui_root() -> impl Element {
let counter = Mutable::new(0);
El::::new()
.height(Val::Percent(100.))
.width(Val::Percent(100.))
.align_content(Align::center())
.child(
Row::::new()
.with_style(|mut style| style.column_gap = Val::Px(15.0))
.item(counter_button(counter.clone(), "-", -1))
.item(El::::new().text_signal(counter.signal().map(text)))
.item(counter_button(counter.clone(), "+", 1))
.update_raw_el(move |raw_el| raw_el.insert(Counter(counter))),
)
}fn counter_button(counter: Mutable, label: &str, step: i32) -> impl Element {
let hovered = Mutable::new(false);
El::::new()
.width(Val::Px(45.0))
.align_content(Align::center())
.background_color_signal(
hovered
.signal()
.map_bool(|| Color::hsl(300., 0.75, 0.85), || Color::hsl(300., 0.75, 0.75))
.map(BackgroundColor),
)
.hovered_sync(hovered)
.on_click(move || *counter.lock_mut() += step)
.child(El::::new().text(text(label)))
}fn text(text: impl ToString) -> Text {
Text::from_section(
text.to_string(),
TextStyle {
font_size: 30.0,
..default()
},
)
}fn camera(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
}
```All examples are compiled to wasm for both webgl2 and webgpu (check [compatibility]()) and deployed to github pages.
- [**`counter`**](https://github.com/databasedav/haalka/blob/main/examples/counter.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/counter/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/counter/)
the example above, a simple counter
- [**`button`**](https://github.com/databasedav/haalka/blob/main/examples/button.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/button/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/button/)
a basic button, port of
- [**`align`**](https://github.com/databasedav/haalka/blob/main/examples/align.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/align/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/align/)
alignment API demo, port of and
- [**`scroll`**](https://github.com/databasedav/haalka/blob/main/examples/scroll.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/scroll/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/scroll/)
scrollability API demo, inspired by
- [**`scroll_grid`**](https://github.com/databasedav/haalka/blob/main/examples/scroll_grid.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/scroll_grid/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/scroll_grid/)
i can't believe it's not scrolling!
- [**`snake`**](https://github.com/databasedav/haalka/blob/main/examples/snake.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/snake/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/snake/)
the classic, with adjustable grid size and tick rate
- [**`ecs_ui_sync`**](https://github.com/databasedav/haalka/blob/main/examples/ecs_ui_sync.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/ecs_ui_sync/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/ecs_ui_sync/)
forward ecs changes to the ui
- [**`key_values_sorted`**](https://github.com/databasedav/haalka/blob/main/examples/key_values_sorted.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/key_values_sorted/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/key_values_sorted/)
text inputs, scrolling/viewport control, and reactive lists; promises made promises kept! (yes I take requests)
- [**`calculator`**](https://github.com/databasedav/haalka/blob/main/examples/calculator.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/calculator/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/calculator/)
simple calculator, spurred by
- [**`main_menu`**](https://github.com/databasedav/haalka/blob/main/examples/main_menu.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/main_menu/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/main_menu/)
sub menus, sliders, dropdowns, reusable composable widgets, gamepad navigation
- [**`inventory`**](https://github.com/databasedav/haalka/blob/main/examples/inventory.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/inventory/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/inventory/)
grid, icons, drag and drop, tooltips
- [**`healthbar`**](https://github.com/databasedav/haalka/blob/main/examples/healthbar.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/healthbar/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/healthbar/)
3D character anchor, customizable widgets
- [**`responsive_menu`**](https://github.com/databasedav/haalka/blob/main/examples/responsive_menu.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/responsive_menu/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/responsive_menu/)
nine-patch buttons, screen size reactivity
- [**`character_editor`**](https://github.com/databasedav/haalka/blob/main/examples/character_editor.rs) [webgl2](https://databasedav.github.io/haalka/examples/webgl2/character_editor/) [webgpu](https://databasedav.github.io/haalka/examples/webgpu/character_editor/)
scrollable buttons, mutable viewport, text input reactivity
Or run them locally with `cargo`.
```bash
cargo run --example counter
cargo run --example button
cargo run --example align
cargo run --example scroll
cargo run --example scroll_grid
cargo run --example snake
cargo run --example ecs_ui_sync
cargo run --example key_values_sorted
cargo run --example calculator# ui challenges from https://github.com/bevyengine/bevy/discussions/11100
cargo run --example main_menu
cargo run --example inventory
cargo run --example healthbar
cargo run --example responsive_menu
cargo run --example character_editor
```
Or with [`just`](https://github.com/casey/just), e.g. `just example snake -r`.## Bevy compatibility
|bevy|haalka|
|-|-|
|`0.14`|`0.2`|
|`0.13`|`0.1`|## development
1. include submodules when fetching the repo
```bash
git clone --recurse-submodules https://github.com/databasedav/haalka.git
```
1. install [just](https://github.com/casey/just?tab=readme-ov-file#installation)
1. install [nickel](https://github.com/tweag/nickel?tab=readme-ov-file#run) for modifying CI configuration (`nickel` must be in your PATH)
1. install [File Watcher](https://marketplace.visualstudio.com/items?itemName=appulate.filewatcher) for automatically syncing nickels## license
All code in this repository is dual-licensed under either:- MIT License ([LICENSE-MIT](https://github.com/databasedav/haalka/blob/main/LICENSE-MIT) or )
- Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/databasedav/haalka/blob/main/LICENSE-APACHE) or )at your option.
Assets used in examples may be licensed under different terms, see the [`examples` README](https://github.com/databasedav/haalka/blob/main/examples/README.md).
### your contributions
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.