iocraft/
lib.rs

1//! # iocraft
2//!
3//! `iocraft` is a library for crafting beautiful text output and interfaces for the terminal or
4//! logs. It allows you to easily build complex layouts and interactive elements using a
5//! declarative API.
6//!
7//! ## Features
8//!
9//! - Define your UI using a clean, highly readable syntax.
10//! - Organize your UI using flexbox layouts powered by [`taffy`](https://docs.rs/taffy/).
11//! - Output colored and styled UIs to the terminal or ASCII output anywhere else.
12//! - Create animated or interactive elements with event handling and hooks.
13//! - Build fullscreen terminal applications with ease.
14//! - Pass [props](crate::Props) and [context](crate::components::ContextProvider) by reference to avoid unnecessary cloning.
15//!
16//! ## Getting Started
17//!
18//! If you're familiar with React, you'll feel right at home with `iocraft`. It uses all the same
19//! concepts, but is text-focused and made for Rust.
20//!
21//! Here's your first `iocraft` program:
22//!
23//! ```
24//! use iocraft::prelude::*;
25//!
26//! fn main() {
27//!     element! {
28//!         View(
29//!             border_style: BorderStyle::Round,
30//!             border_color: Color::Blue,
31//!         ) {
32//!             Text(content: "Hello, world!")
33//!         }
34//!     }
35//!     .print();
36//! }
37//! ```
38//!
39//! Your UI is composed primarily via the [`element!`] macro, which allows you to declare your UI
40//! elements in a React/SwiftUI-like syntax.
41//!
42//! `iocraft` provides a few built-in components in the [`components`] module, such as
43//! [`View`](crate::components::View), [`Text`](crate::components::Text), and
44//! [`TextInput`](crate::components::TextInput), but you can also create your own using the
45//! [`macro@component`] macro.
46//!
47//! For example, here's a custom component that uses a [hook](crate::hooks) to display a counter
48//! which increments every 100ms:
49//!
50//! ```no_run
51//! # use iocraft::prelude::*;
52//! # use std::time::Duration;
53//! #[component]
54//! fn Counter(mut hooks: Hooks) -> impl Into<AnyElement<'static>> {
55//!     let mut count = hooks.use_state(|| 0);
56//!
57//!     hooks.use_future(async move {
58//!         loop {
59//!             smol::Timer::after(Duration::from_millis(100)).await;
60//!             count += 1;
61//!         }
62//!     });
63//!
64//!     element! {
65//!         Text(color: Color::Blue, content: format!("counter: {}", count))
66//!     }
67//! }
68//! ```
69//!
70//! ## More Examples
71//!
72//! There are many [examples on GitHub](https://github.com/ccbrown/iocraft/tree/main/examples)
73//! which demonstrate various concepts such as tables, progress bars, full screen apps, forms, and
74//! more!.
75//!
76//! ## Shoutouts
77//!
78//! `iocraft` was inspired by [Dioxus](https://github.com/DioxusLabs/dioxus) and
79//! [Ink](https://github.com/vadimdemedes/ink), which you should also check out, especially if
80//! you're building graphical interfaces or interested in using JavaScript/TypeScript.
81//!
82//! You may also want to check out [Ratatui](https://github.com/ratatui/ratatui), which serves a
83//! similar purpose with a less declarative API.
84
85#![allow(clippy::needless_doctest_main)]
86#![warn(missing_docs)]
87
88// # Organization
89//
90// Code is organized into modules primarily for the benefit of the maintainers. Types will be
91// re-exported in the root so that users of the library have a flat namespace to work with.
92//
93// The exception is the modules that represent collections of types, namely hooks and components.
94// Those types will remain in their modules for the public API.
95
96mod canvas;
97mod component;
98mod context;
99mod element;
100mod handler;
101mod hook;
102mod multimap;
103mod props;
104mod render;
105pub(crate) mod segmented_string;
106mod style;
107mod terminal;
108pub(crate) mod unicode_linebreak;
109
110mod flattened_exports {
111    pub use crate::canvas::*;
112    pub use crate::component::*;
113    pub use crate::context::*;
114    pub use crate::element::*;
115    pub use crate::handler::*;
116    pub use crate::hook::*;
117    pub use crate::props::*;
118    pub use crate::render::*;
119    pub use crate::style::*;
120    pub use crate::terminal::*;
121
122    pub use iocraft_macros::*;
123}
124
125pub use flattened_exports::*;
126
127/// Components for crafting your UI.
128pub mod components;
129
130pub mod hooks;
131
132/// By importing this module, you'll bring all of the crate's commonly used types into scope.
133pub mod prelude {
134    pub use crate::components::*;
135    pub use crate::flattened_exports::*;
136    pub use crate::hooks::*;
137}
138
139// So we can use our own macros.
140extern crate self as iocraft;