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