Expand description
Floem
Floem is cross-platform GUI framework for Rust 🦀. It aims to be extremely performant while providing world-class developer ergonomics.
Views
Floem models the UI using a tree of View instances that is constructed once. Views are self-contained components that can be composed together to create complex UIs, capable of reacting to state changes and events.
To ensure good UI performance, view composition functions are not rerun in response to changes in the reactive system. Unnecessary rebuilds of views can be expensive. If you have a use case for which having a view composition function that responds to reactivity is essential, you may wish to consider dyn_container.
You can read more about authoring your own views or see all built-in views.
Widgets
Widgets are specialized high-level views providing certain functionality. Common examples include buttons, labels or text input fields. For a list of Floem’s built-in widgets, refer here. You can try them out via the widget gallery example.
State management
Floem uses reactivity built on signals and effects for its state management. This design pattern has been popularized by SolidJS in the JavaScript ecosystem and directly inspired Leptos in the Rust ecosystem. Floem uses its own reactive system with an API that is nearly identical to the one in the leptos_reactive crate. To learn more about signals and effects, you may want to explore Leptos’ documentation and their book.
Local state
You can create a signal anywhere in the program using create_rw_signal
or create_signal
. When you use a signal’s value within a view by calling
get
or with
,
the runtime will automatically subscribe the correct side effects
to changes in that signal, creating reactivity. To the programmer this is transparent. The reactivity
“just works” by accessing the value where you want to use it.
fn app_view() -> impl View {
let text = create_rw_signal("Hello world".to_string());
v_stack((text_input(text), label(move || text.get()))).style(|s| s.padding(10.0))
}
In this example, text
is a signal containing a String
that can both be read from and written to.
The signal is used in two different places in the vertical stack.
The text input has direct access to the RwSignal
and will mutate the underlying String
when the user types in the input box. The reactivity will then
trigger a rerender of the label with the updated text value.
create_signal
returns a separated
ReadSignal
and WriteSignal
for a variable.
An existing RwSignal
may be converted using RwSignal::read_only
and RwSignal::write_only
where necessary, but the reverse is not
possible.
Global state
Global state can be implemented using provide_context and use_context.
Customizing appearance
You can style a View instance by calling its style
method. You’ll need to import the
floem::views::Decorators
trait to use it. The style
method takes a function exposing a
Style
parameter. Through this parameter, you can access methods that modify a variety
of familiar properties like width, padding and background. Some Style
properties
such as font size are inherited from parent views and can be overridden.
Styles can be updated reactively using any signal. Here’s how to apply a gray background color while the value
held by the active_tab
signal equals 0:
label(|| "Some text").style(move |s| {
s.flex_row()
.width(100.pct())
.height(32.0)
.border_bottom(1.0)
.border_color(Color::LIGHT_GRAY)
.apply_if(active_tab.get() == 0, |s| s.background(Color::GRAY))
});
For additional information about styling, see here.
Themes and widget customizations
Floem widgets ship with default styling that can be customized to your liking using style
classes. Take the text input widget
for example: it exposes a style class TextInputClass
. Any styling rules that are attached
to this class using Style’s class
method will be applied to the text input.
Widgets may expose multiple classes to enable customization of different aspects of their UI. The
labeled checkbox is an example of this: both the checkbox itself and the label next to it can
be customized using CheckboxClass
and LabeledCheckboxClass
respectively.
To theme a window, call the style
method on your root view and inject
your stylesheet. In your WindowConfig
, you may want to disable the
injection of Floem’s default styling. The
themes
example is available
as a reference.
Don’t have the time or patience to develop your own theme? Check the floem-themes GitHub topic for a list of reusable themes made by the community. This list is unmoderated.
Additional reading
Re-exports
pub use context::EventPropagation;
pub use window::close_window;
pub use window::new_window;
pub use floem_peniko as peniko;
pub use floem_reactive as reactive;
pub use floem_renderer::cosmic_text;
pub use kurbo;
pub use taffy;
Modules
- Ids
- Renderer
- Style
- Views
- Floem builtin Views
- Floem widgets
Macros
Structs
- Floem top level application This is the entry point of the application.