concoct/lib.rs
1//! A UI framework for writing declarative apps on multiple platforms.
2//!
3//! Concoct uses static typing to describe your UI at compile-time
4//! to create an efficient tree of components. Updates to state re-render
5//! your application top-down, starting at the state's parent component.
6//!
7//! ```ignore
8//! use concoct::{View, ViewBuilder};
9//! use concoct::hook::use_state;
10//! use concoct_web::html;
11//!
12//! struct App;
13//!
14//! impl ViewBuilder for App {
15//! fn build(&self) -> impl View {
16//! let (count, set_high) = use_state(|| 0);
17//! let set_low = set_high.clone();
18//!
19//! (
20//! format!("High five count: {}", count),
21//! html::button("Up high!").on_click(move |_| set_high(count + 1)),
22//! html::button("Down low!").on_click(move |_| set_low(count - 1)),
23//! )
24//! }
25//! }
26//! ```
27//!
28//! ## Feature flags
29//! - `full`: Enables all of the features below.
30//! - `tracing`: Enables logging with the `tracing` crate.
31//!
32
33use std::borrow::Cow;
34use std::cell::RefCell;
35
36pub mod hook;
37
38mod macros;
39
40mod rt;
41pub(crate) use self::rt::{Runtime, Scope};
42
43mod tree;
44pub(crate) use tree::Node;
45pub use tree::Tree;
46
47mod vdom;
48pub use self::vdom::VirtualDom;
49
50mod view_builder;
51pub use self::view_builder::ViewBuilder;
52
53pub mod view;
54pub use self::view::View;
55
56/// Run a view in a new virtual dom.
57pub async fn run(view: impl ViewBuilder) {
58 let mut vdom = VirtualDom::new(view.into_tree());
59 vdom.build();
60
61 loop {
62 vdom.rebuild().await
63 }
64}
65
66/// Provider for a platform-specific text view.
67///
68/// If you're writing a custom backend, you can use this to override
69/// the default implementation of `View` for string types (like `&str` and `String`).
70///
71/// To expose it to child views, use [`use_provider`](`crate::hook::use_provider`).
72pub struct TextViewContext {
73 view: RefCell<Box<dyn FnMut(Cow<'static, str>)>>,
74}
75
76impl TextViewContext {
77 /// Create a text view context from a view function.
78 ///
79 /// Text-based views, such as `&str` or `String` will call
80 /// this view function on when rendered.
81 pub fn new(view: impl FnMut(Cow<'static, str>) + 'static) -> Self {
82 Self {
83 view: RefCell::new(Box::new(view)),
84 }
85 }
86}