### Hello World Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/README.md A basic 'Hello, world!' example demonstrating the element! macro for creating a simple View with Text. The output is printed to the console. ```rust use iocraft::prelude::*; fn main() { element! { View(border_style: BorderStyle::Round, border_color: Color::Blue) { Text(content: "Hello, world!") } } .print(); } ``` -------------------------------- ### Run iocraft example Source: https://github.com/ccbrown/iocraft/blob/main/examples/README.md Command to run a specific iocraft example. Replace NAME with the example's filename (e.g., table). ```bash cargo run --example table ``` -------------------------------- ### Full Render Loop Configuration Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/configuration.md An example demonstrating the configuration of a render loop with fullscreen and mouse capture enabled. ```rust use iocraft::prelude::*; #[component]fn InteractiveApp(mut hooks: Hooks) -> impl Into> { // Component implementation element!(View { Text(content: "Interactive app") }) } #[smol_macros::main]async fn main() -> std::io::Result<()> { element!(InteractiveApp) .render_loop() .fullscreen() .enable_mouse_capture() .await } ``` -------------------------------- ### Basic Button Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-button.md A simple example demonstrating how to create a button with a click handler and text content. ```rust use iocraft::prelude::*; element! { Button(handler: |_| { println!("Clicked!"); }, has_focus: true) { View(border_style: BorderStyle::Round, border_color: Color::Blue) { Text(content: "Click me!") } } } ``` -------------------------------- ### Example: Creating a Handler from Fn Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/handlers.md Shows the basic usage of converting a simple Fn closure into a Handler. ```rust use iocraft::prelude::*; let handler: Handler = Handler::from(|value| println!("{}", value)); ``` -------------------------------- ### Complete Terminal Event Handling Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/terminal-events.md A comprehensive example showing how to handle various terminal events, including global exit keys, mode switching, navigation, mouse clicks, and window resizing, using the `use_terminal_events` hook. ```rust use iocraft::prelude::*; #[component] fn InteractiveApp(mut hooks: Hooks) -> impl Into> { let mut mode = hooks.use_state(|| "navigation"); let mut selected = hooks.use_state(|| 0); let mut text_input = hooks.use_state(|| "".to_string()); hooks.use_terminal_events(move |event| { match event { // Global exit key TerminalEvent::Key(KeyEvent { code: KeyCode::Char('q'), kind: KeyEventKind::Press, .. }) => { let mut system = hooks.use_context_mut::(); system.exit(); } // Mode switching TerminalEvent::Key(KeyEvent { code: KeyCode::Char(':'), kind: KeyEventKind::Press, .. }) => { mode.set("command"); } // Navigation TerminalEvent::Key(KeyEvent { code: KeyCode::Up, kind: KeyEventKind::Press, .. }) if mode.get() == "navigation" => { selected.set(selected.get().saturating_sub(1)); } TerminalEvent::Key(KeyEvent { code: KeyCode::Down, kind: KeyEventKind::Press, .. }) if mode.get() == "navigation" => { selected.set(selected.get() + 1); } // Mouse clicks TerminalEvent::FullscreenMouse(FullscreenMouseEvent { kind: MouseEventKind::Down(_), column, row, .. }) => { println!("Clicked at ({}, {})", column, row); } // Window resize TerminalEvent::Resize(width, height) => { println!("Terminal resized to {}x{}", width, height); } _ => {} } }); element! { View { Text(content: format!("Mode: {}", mode)) Text(content: format!("Selected: {}", selected)) } } } ``` -------------------------------- ### TextInput with Imperative Cursor Control Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Demonstrates how to control the text input cursor imperatively using a `TextInputHandle`. This example shows moving the cursor to the beginning or end of the line with keyboard shortcuts. ```rust use iocraft::prelude::*; #[component] fn InputWithControls(mut hooks: Hooks) -> impl Into> { let mut value = hooks.use_state(|| "Hello".to_string()); let mut handle = hooks.use_ref_default::(); hooks.use_terminal_events({ let mut handle = handle; move |event| { match event { TerminalEvent::Key(KeyEvent { code: KeyCode::Home, .. }) => { handle.write().set_cursor_offset(0); } TerminalEvent::Key(KeyEvent { code: KeyCode::End, .. }) => { handle.write().set_cursor_offset(value.len()); } _ => {} } } }); element! { View(width: 60, padding: 1) { Text(content: format!("Cursor at: {}", handle.read().cursor_offset())) TextInput( has_focus: true, value: value.to_string(), on_change: move |new_value| value.set(new_value), handle, cursor_color: Color::Yellow, ) } } } ``` -------------------------------- ### Example: HandlerMut take Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/handlers.md Shows how to use the take method to retrieve the original handler and leave a default handler in its place. ```rust use iocraft::prelude::*; let mut handler = HandlerMut::from(|x: i32| println!("{}", x)); let taken = handler.take(); assert!(handler.is_default()); ``` -------------------------------- ### Example: Getting Cursor Offset Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Shows how to read the current cursor offset from a TextInputHandle. ```rust let position = handle.read().cursor_offset(); ``` -------------------------------- ### Example: Setting Element Size with Percent Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Demonstrates using the `pct` suffix to define element width and height as percentages of the parent size. ```rust use iocraft::prelude::*; element! { View( width: 50pct, // Percent(50.0) height: 25pct, ) { Text(content: "Half width") } } ``` -------------------------------- ### ScrollView with Imperative Control Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-other.md Shows how to use a ScrollView with a handle for imperative control, responding to keyboard events to scroll the content. ```rust use iocraft::prelude::*; #[component] fn ScrollWithControls(mut hooks: Hooks) -> impl Into> { let handle = hooks.use_ref_default::(); hooks.use_terminal_events({ let mut handle = handle; move |event| { match event { TerminalEvent::Key(KeyEvent { code: KeyCode::Home, .. }) => { handle.write().scroll_to_top(); } TerminalEvent::Key(KeyEvent { code: KeyCode::End, .. }) => { handle.write().scroll_to_bottom(); } TerminalEvent::Key(KeyEvent { code: KeyCode::PageUp, .. }) => { handle.write().scroll_by(-10); } TerminalEvent::Key(KeyEvent { code: KeyCode::PageDown, .. }) => { handle.write().scroll_by(10); } _ => {} } } }); element! { View(width: 80, height: 24) { ScrollView(handle) { // Content... } } } } ``` -------------------------------- ### Multiple Buttons Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-button.md Shows how to implement multiple buttons within a single component, each controlling different aspects of the state. ```rust use iocraft::prelude::*; #[component] fn App(mut hooks: Hooks) -> impl Into> { let mut counter = hooks.use_state(|| 0); element! { View(flex_direction: FlexDirection::Column, gap: 2) { Text(content: format!("Value: {}", counter), weight: Weight::Bold) View(flex_direction: FlexDirection::Row, gap: 2) { Button( handler: move |_| counter += 1, has_focus: true, ) { Text(content: "[ + ]") } Button( handler: move |_| if counter > 0 { counter -= 1 }, has_focus: false, ) { Text(content: "[ - ]") } } } } } ``` -------------------------------- ### TextInput Form with Validation Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Illustrates using multiple TextInput components within a form, managing focus between fields. This example sets up basic structure for form input. ```rust use iocraft::prelude::*; #[component] fn LoginForm(mut hooks: Hooks) -> impl Into> { let mut username = hooks.use_state(|| "".to_string()); let mut password = hooks.use_state(|| "".to_string()); let mut focus_field = hooks.use_state(|| 0); element! { View( width: 40, padding: 2, border_style: BorderStyle::Single, border_color: Color::Blue, flex_direction: FlexDirection::Column, gap: 1, ) { Text(content: "Username", weight: Weight::Bold) TextInput( has_focus: focus_field.get() == 0, value: username.to_string(), on_change: move |new_value| username.set(new_value), ) Text(content: "Password", weight: Weight::Bold) TextInput( has_focus: focus_field.get() == 1, value: password.to_string(), on_change: move |new_value| password.set(new_value), ) } } } ``` -------------------------------- ### Example: Setting Element Size Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Demonstrates setting element width and height using the Size enum variants, including Length and Percent, via the element! macro. ```rust use iocraft::prelude::*; element! { View( width: 80, // Length(80) height: 24pct, // Percent(24.0) max_width: 100, // Length(100) ) { Text(content: "Content") } } ``` -------------------------------- ### UseState Hook: Counter Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Demonstrates how to create and manage mutable state using the `use_state` hook. This example shows a simple counter component that increments its state when a button is clicked. ```rust use iocraft::prelude::*; #[component] fn Counter(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); element! { View(flex_direction: FlexDirection::Column, gap: 1) { Text(content: format!("Count: {}", count.get())) Button(handler: move |_| count += 1, has_focus: true) { Text(content: "Increment") } } } } ``` -------------------------------- ### Styled Text Component Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text.md Demonstrates styling the Text component with different colors, weights, decorations, and italic/invert properties. ```rust use iocraft::prelude::*; element! { View(flex_direction: FlexDirection::Column, gap: 1) { Text( content: "Bold Blue Text", color: Color::Blue, weight: Weight::Bold, ) Text( content: "Underlined Red Text", color: Color::Red, decoration: TextDecoration::Underline, ) Text( content: "Italic Green Text", color: Color::Green, italic: true, ) Text( content: "Inverted Colors", invert: true, ) } } ``` -------------------------------- ### UseMemo Hook Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Illustrates `use_memo` by calculating the sum of numbers up to a given input. The sum is recomputed only when the input value changes. ```rust use iocraft::prelude::*; #[component] fn ExpensiveComputation(mut hooks: Hooks) -> impl Into> { let mut input = hooks.use_state(|| 5); let result = hooks.use_memo( move || (0..input.get()).sum::(), input.get(), ); element!(Text(content: format!("Sum: {}", result))) } ``` -------------------------------- ### Basic ScrollView Usage Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-other.md Demonstrates a basic ScrollView implementation displaying a list of items that may exceed the viewport height. ```rust use iocraft::prelude::*; #[component] fn ScrollableList(mut hooks: Hooks) -> impl Into> { element! { View(width: 80, height: 20) { ScrollView { Text(content: "Item 1") Text(content: "Item 2") Text(content: "Item 3") // ... many more items } } } } ``` -------------------------------- ### Example: Mock Terminal Rendering with Input Events Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/element.md Demonstrates how to use `mock_terminal_render_loop` with a custom component and simulate user input events. The output is collected as a vector of strings. ```rust use iocraft::prelude::*; use futures::stream::{StreamExt, iter}; #[component] fn MyInput(mut hooks: Hooks) -> impl Into> { let mut value = hooks.use_state(|| "".to_string()); element!(TextInput( value: value.to_string(), on_change: move |new_value| value.set(new_value), has_focus: true, )) } #[smol_macros::main] async fn main() { let output = element!(MyInput) .mock_terminal_render_loop( MockTerminalConfig::with_events(iter(vec![ TerminalEvent::Key(KeyEvent::new(KeyEventKind::Press, KeyCode::Char('a'))), ])) ) .map(|c| c.to_string()) .collect::>() .await; } ``` -------------------------------- ### Configure Render Loop Output to Stderr Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/configuration.md Example demonstrating how to configure a render loop to use a custom stderr writer and direct output to stderr. ```rust use iocraft::prelude::*; use std::io::LineWriter; #[smol_macros::main]async fn main() { let stderr = LineWriter::new(std::io::stderr()); element!(MyApp) .render_loop() .output(Output::Stderr) .stderr(stderr) .await .unwrap(); } ``` -------------------------------- ### Example: Setting Element Margin Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Shows how to apply margins to an element using the Margin enum variants for individual sides or all sides. ```rust use iocraft::prelude::*; element! { View( margin: 2, // Length(2) margin_top: 1, margin_left: 5pct, // Percent(5.0) ) { Text(content: "Content") } } ``` -------------------------------- ### UseFuture Hook: Auto Increment Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Shows how to spawn an asynchronous future using `use_future` that runs concurrently with the component. This example creates a counter that increments automatically every 500 milliseconds. ```rust use iocraft::prelude::*; use std::time::Duration; #[component] fn AutoIncrement(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); hooks.use_future(async move { loop { smol::Timer::after(Duration::from_millis(500)).await; count += 1; } }); element!(Text(content: format!("Count: {}", count))) } ``` -------------------------------- ### Text Wrapping and Alignment Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text.md Shows how to use TextWrap::Wrap and TextAlign::Center to manage text flow and alignment within a fixed-width container. ```rust use iocraft::prelude::*; element! { View(width: 30, padding: 1) { Text( content: "This is a longer piece of text that will wrap at word boundaries to fit within the container", wrap: TextWrap::Wrap, align: TextAlign::Center, ) } } ``` -------------------------------- ### Complex Layout Configuration Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/configuration.md Demonstrates how to configure a complex layout using various ViewProps like width, height, padding, background color, flex direction, and gap. It shows nested views for header, sidebar, and main content areas with specific alignment and sizing. ```rust use iocraft::prelude::*; element! { View( width: 100, height: 30, padding: 2, background_color: Color::DarkGrey, flex_direction: FlexDirection::Column, gap: 1, ) { // Header View( height: 3, padding: 1, background_color: Color::DarkBlue, justify_content: JustifyContent::Center, ) { Text(content: "Header", weight: Weight::Bold, color: Color::White) } // Main content area View( flex: 1, flex_direction: FlexDirection::Row, gap: 2, ) { // Sidebar View( width: 20pct, background_color: Color::DarkRed, padding: 1, ) { Text(content: "Sidebar") } // Content View( flex: 1, padding: 1, ) { Text(content: "Main content") } } } } ``` -------------------------------- ### Example: Setting Cursor Offset on Mount Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Demonstrates how to use TextInputHandle to set the cursor offset to the beginning of the input when the component mounts. Requires importing iocraft::prelude::*. ```rust use iocraft::prelude::*; #[component] fn FormField(mut hooks: Hooks) -> impl Into> { let mut value = hooks.use_state(|| "".to_string()); let mut handle = hooks.use_ref_default::(); hooks.use_effect( move || handle.write().set_cursor_offset(0), (), ); element! { TextInput( has_focus: true, value: value.to_string(), on_change: move |new_value| value.set(new_value), handle, ) } } ``` -------------------------------- ### Multiline TextInput Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Shows how to configure the TextInput component for multiline input, suitable for text editors. The `multiline: true` prop enables this behavior. ```rust use iocraft::prelude::*; #[component] fn TextEditor(mut hooks: Hooks) -> impl Into> { let mut content = hooks.use_state(|| "".to_string()); element! { View(width: 80, height: 20, padding: 1) { Text(content: "Editor:", weight: Weight::Bold) TextInput( has_focus: true, value: content.to_string(), on_change: move |new_value| content.set(new_value), multiline: true, color: Color::White, ) } } } ``` -------------------------------- ### UseContext Hook Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Demonstrates how to use the `use_context` hook to access a `Theme` struct and apply its primary color to a button's text. ```rust use iocraft::prelude::*; struct Theme { primary_color: Color, } #[component] fn ThemedButton(hooks: Hooks) -> impl Into> { let theme = hooks.use_context::(); element! { Button(handler: |_| {}, has_focus: true) { Text(content: "Click me", color: Some(theme.primary_color)) } } } ``` -------------------------------- ### Example: Setting Element Padding Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Illustrates setting padding for an element, including individual sides and horizontal padding, using the Padding enum. ```rust use iocraft::prelude::*; element! { View( padding: 2, // Padding::Length(2) on all sides padding_top: 1, padding_horizontal: 3, ) { Text(content: "Content") } } ``` -------------------------------- ### UseState Hook: Default String Input Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Illustrates using `use_state_default` to initialize state with the default value for its type. This example creates a text input field that defaults to an empty string. ```rust use iocraft::prelude::*; #[component] fn Form(mut hooks: Hooks) -> impl Into> { let mut text = hooks.use_state_default::(); element! { TextInput( has_focus: true, value: text.to_string(), on_change: move |new_value| text.set(new_value), ) } } ``` -------------------------------- ### Single-line TextInput Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Demonstrates a basic single-line text input for search functionality. It uses `use_state` to manage the input value and `on_change` to update it. ```rust use iocraft::prelude::*; #[component] fn SearchField(mut hooks: Hooks) -> impl Into> { let mut search_value = hooks.use_state(|| "".to_string()); element! { View(width: 50, padding: 1) { Text(content: "Search:", color: Color::White) TextInput( has_focus: true, value: search_value.to_string(), on_change: move |new_value| search_value.set(new_value), color: Color::Cyan, ) } } } ``` -------------------------------- ### Example: Setting Gap Between Flex Items Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Demonstrates setting the gap between flex items using the Gap enum, including row-specific gaps. ```rust use iocraft::prelude::*; element! { View( flex_direction: FlexDirection::Column, gap: 1, // Gap::Length(1) between items row_gap: 2, ) { Text(content: "Item 1") Text(content: "Item 2") } } ``` -------------------------------- ### UseTerminalSize Hook Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Demonstrates how to use the use_terminal_size hook within a component to display the terminal dimensions. ```rust use iocraft::prelude::*; #[component] fn TerminalInfo(mut hooks: Hooks) -> impl Into> { let (width, height) = hooks.use_terminal_size(); element! { View { Text(content: format!("Terminal size: {}x{}", width, height)) } } } ``` -------------------------------- ### Example: Cloning a Handler Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/handlers.md Demonstrates that Handler is Cloneable due to its internal Arc, allowing multiple references to the same handler. ```rust use iocraft::prelude::*; let handler: Handler = Handler::from(|x| println!("{}", x)); let handler_clone = handler.clone(); ``` -------------------------------- ### UseRef Hook Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Shows how to use `use_ref_default` to create a handle for a `TextInput` component, allowing external control without causing re-renders. ```rust use iocraft::prelude::*; #[component] fn InputWithHandle(mut hooks: Hooks) -> impl Into> { let mut handle = hooks.use_ref_default::(); element! { TextInput( has_focus: true, value: "".to_string(), on_change: move |_| {}, handle, ) } } ``` -------------------------------- ### Mock Terminal Rendering for Testing Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/README.md Provides an example of how to test IoCraft components using mock terminal rendering. This snippet simulates keyboard input and asserts the resulting terminal output. ```rust #[smol_macros::test] async fn test_text_input() { let actual = element!(MyTextInput) .mock_terminal_render_loop( MockTerminalConfig::with_events(futures::stream::iter(vec![ TerminalEvent::Key(KeyEvent::new(KeyEventKind::Press, KeyCode::Char('a'))), ])) ) .map(|c| c.to_string()) .collect::>() .await; assert_eq!(actual[1], "a\n"); } ``` -------------------------------- ### Create a Reusable Component with #[component] Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md Components are reusable UI units defined using the `#[component]` macro. This example defines a simple button component. ```rust #[component] fn MyButton(mut hooks: Hooks) -> impl Into> { // Component logic element!(Button { Text(content: "Click") }) } ``` -------------------------------- ### Example: Handler bind with component Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/handlers.md Demonstrates using the bind method to create distinct handlers for multiple buttons, each triggering an async state update with a specific choice value. ```rust use iocraft::prelude::*; #[component] fn MultiButton(mut hooks: Hooks) -> impl Into> { let mut selection = hooks.use_state(|| 0); let mut handler = hooks.use_async_handler(move |choice: i32| async move { selection.set(choice); }); element! { Fragment { Button(handler: handler.bind(1), has_focus: true) { Text(content: "[ Option 1 ]") } Button(handler: handler.bind(2), has_focus: false) { Text(content: "[ Option 2 ]") } } } } ``` -------------------------------- ### Implement Component Logic with Hooks Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md Hooks provide behavior to components, such as state management, effects, and context access. This example demonstrates `use_state`, `use_effect`, and `use_context`. ```rust let mut count = hooks.use_state(|| 0); hooks.use_effect(move || println!("count changed"), count.get()); let theme = hooks.use_context::(); ``` -------------------------------- ### UseConst Hook Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Shows how to use the use_const hook to compute and cache an expensive value, like a configuration vector, for the lifetime of a component. ```rust use iocraft::prelude::*; #[component] fn WithConstValue(mut hooks: Hooks) -> impl Into> { let config = hooks.use_const(|| { // Expensive initialization happens once vec![1, 2, 3, 4, 5] }); element!(Text(content: format!("Config: {:?}", config))) } ``` -------------------------------- ### Nested Views in Button Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-button.md Illustrates nesting `View` components within a `Button` to create complex visual structures and conditional styling. ```rust use iocraft::prelude::*; #[component] fn ButtonPanel(mut hooks: Hooks) -> impl Into> { let mut selected = hooks.use_state(|| 0); element! { View( border_style: BorderStyle::Single, border_color: Color::Cyan, padding: 1, ) { Button( handler: move |_| selected.set(1), has_focus: selected.get() == 1, ) { View(background_color: if selected.get() == 1 { Color::Cyan } else { Color::DarkGrey }) { Text(content: "Option 1") } } Button( handler: move |_| selected.set(2), has_focus: selected.get() == 2, ) { View(background_color: if selected.get() == 2 { Color::Cyan } else { Color::DarkGrey }) { Text(content: "Option 2") } } } } } ``` -------------------------------- ### Custom Counter Component with Hooks in iocraft Source: https://github.com/ccbrown/iocraft/blob/main/packages/iocraft/README.md This example shows how to create a custom component in iocraft using the `#[component]` macro and hooks. It utilizes `use_state` to manage a counter and `use_future` to increment it periodically, demonstrating interactive UI elements. ```rust use iocraft::prelude::*; use std::time::Duration; #[component] fn Counter(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); hooks.use_future(async move { loop { smol::Timer::after(Duration::from_millis(100)).await; count += 1; } }); element! { Text(color: Color::Blue, content: format!("counter: {{}}", count)) } } fn main() { smol::block_on(element!(Counter).render_loop()).unwrap(); } ``` -------------------------------- ### Fragment Component Usage Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-other.md Demonstrates how to use the Fragment component to group multiple Text elements within a component. This is useful for returning multiple elements from a component. ```rust use iocraft::prelude::*; #[component] fn TextLines() -> impl Into> { element! { Fragment { Text(content: "Line 1") Text(content: "Line 2") Text(content: "Line 3") } } } #[component] fn App() -> impl Into> { element! { View(flex_direction: FlexDirection::Column) { TextLines } } } ``` -------------------------------- ### Create a custom counter component with hooks in iocraft Source: https://github.com/ccbrown/iocraft/blob/main/README.md This example shows how to create a custom component using the `#[component]` macro. It utilizes `use_state` to manage a counter and `use_future` to increment it periodically, demonstrating asynchronous operations within components. ```rust use iocraft::prelude::*; use std::time::Duration; #[component] fn Counter(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); hooks.use_future(async move { loop { smol::Timer::after(Duration::from_millis(100)).await; count += 1; } }); element! { Text(color: Color::Blue, content: format!("counter: {}", count)) } } fn main() { smol::block_on(element!(Counter).render_loop()).unwrap(); } ``` -------------------------------- ### Example: HandlerMut is_default Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/handlers.md Demonstrates checking the default state of HandlerMut. A default-initialized handler returns true, while one set with a closure returns false. ```rust use iocraft::prelude::*; let handler = HandlerMut::::default(); assert!(handler.is_default()); let handler = HandlerMut::from(|value: i32| println!("{}", value)); assert!(!handler.is_default()); ``` -------------------------------- ### Configure View Layout with Flexbox Properties Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md iocraft uses a Flexbox-based layout system via `taffy`. This example shows how to apply layout properties like `width`, `flex_direction`, `gap`, and `padding` to a View. ```rust element!(View( width: 100, flex_direction: FlexDirection::Column, gap: 1, padding: 2, ) { /* children */ }) ``` -------------------------------- ### Example: Using HandlerMut in a component Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/handlers.md Demonstrates how a mutable closure (FnMut) is automatically converted to a HandlerMut when passed to a component property like 'handler'. ```rust use iocraft::prelude::*; #[component] fn Counter(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); element! { Button( handler: move |_| count += 1, // FnMut converted to HandlerMut has_focus: true, ) { Text(content: "Increment") } } } ``` -------------------------------- ### Handle KeyCode in UI Component Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/terminal-events.md Demonstrates how to handle different KeyCode variants within a UI component to display the last pressed key. This example maps specific key codes to user-friendly strings. ```rust use iocraft::prelude::*; #[component] fn KeyHandler(mut hooks: Hooks) -> impl Into> { let mut last_key = hooks.use_state(|| "".to_string()); hooks.use_terminal_events(move |event| { if let TerminalEvent::Key(KeyEvent { code, .. }) = event { let key_str = match code { KeyCode::Char(c) => format!( ``` ```rust '{}', c), KeyCode::Enter => "Enter".to_string(), KeyCode::Up => "Up Arrow".to_string(), KeyCode::F(n) => format!("F{}", n), _ => format!("{:?}", code), }; last_key.set(key_str); } }); element!(Text(content: format!("Last key: {}", last_key))) ``` -------------------------------- ### Handle Terminal Resize Events Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/terminal-events.md This example demonstrates how to use the `use_terminal_events` hook to capture terminal resize events and update the application's state with the new dimensions. ```rust use iocraft::prelude::*; #[component] fn SizeAware(mut hooks: Hooks) -> impl Into> { let mut terminal_size = hooks.use_state(|| (0u16, 0u16)); hooks.use_terminal_events(move |event| { if let TerminalEvent::Resize(width, height) = event { terminal_size.set((width, height)); } }); let (width, height) = terminal_size.get(); element! { Text(content: format!("Terminal: {}x{}", width, height)) } } ``` -------------------------------- ### Start AnyElement render loop Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/element.md Returns a future that continuously renders the AnyElement, enabling dynamic and interactive components. This method is part of the ElementExt trait. ```rust pub fn render_loop(&mut self) -> RenderLoopFuture<'_, Self> ``` ```rust use iocraft::prelude::*; #[component] fn MyApp(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); hooks.use_future(async move { loop { smol::Timer::after(std::time::Duration::from_millis(100)).await; count += 1; } }); element!(Text(content: format!("Count: {}", count))) } #[smol_macros::main] async fn main() { element!(MyApp).render_loop().await.unwrap(); } ``` -------------------------------- ### API Reference Details Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/_MANIFEST.txt The iocraft API reference provides detailed documentation for over 150 methods, including type signatures, parameter descriptions, return values, usage examples, and error conditions. ```APIDOC ## API Reference Details The iocraft library documents over 150 methods. Each documented API includes: - Complete type signature. - Parameter descriptions with types and defaults. - Return type and description. - Usage examples (tested for syntax). - Error conditions (where applicable). - Source file location reference. ``` -------------------------------- ### UseTerminalEvents Hook Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Demonstrates `use_terminal_events` to capture keyboard input and update the last pressed key. The component displays the code of the last key event received. ```rust use iocraft::prelude::*; #[component] fn KeyLogger(mut hooks: Hooks) -> impl Into> { let mut last_key = hooks.use_state(|| "".to_string()); hooks.use_terminal_events(move |event| { if let TerminalEvent::Key(key_event) = event { last_key.set(format!("{:?}", key_event.code)); } }); element!(Text(content: format!("Last key: {}", last_key))) } ``` -------------------------------- ### Simple Counter Component Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md A basic example of a stateful component using `hooks.use_state` to manage a counter. It displays the current count and updates it when interacted with (though interaction logic is not shown here). ```rust #[component] fn Counter(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); element!(Text(content: format!("Count: {}", count.get()))) } ``` -------------------------------- ### Basic "Hello, world!" CLI with iocraft Source: https://github.com/ccbrown/iocraft/blob/main/packages/iocraft/README.md This is the simplest way to print text to the console using iocraft. It demonstrates the basic structure of an iocraft application using the `element!` macro and the `print()` method. ```rust use iocraft::prelude::*; fn main() { element! { View( border_style: BorderStyle::Round, border_color: Color::Blue, ) { Text(content: "Hello, world!") } } .print(); } ``` -------------------------------- ### Basic Text Component Usage Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text.md Renders a simple text string 'Hello, world!' using the Text component. ```rust use iocraft::prelude::*; element! { Text(content: "Hello, world!") } ``` -------------------------------- ### Get Canvas Dimensions Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/canvas.md Retrieves the width and height of the canvas in characters. ```rust pub fn width(&self) -> usize ``` ```rust pub fn height(&self) -> usize ``` -------------------------------- ### UseTerminalSize Hook Definition Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/hooks.md Defines the UseTerminalSize trait for getting the current terminal dimensions. ```rust pub trait UseTerminalSize: Sealed { fn use_terminal_size(&mut self) -> (u16, u16); } ``` -------------------------------- ### Get Cursor Offset from TextInputHandle Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Retrieves the current cursor position in bytes from the TextInputHandle. ```rust pub fn cursor_offset(&self) -> usize ``` -------------------------------- ### TextInputHandle Methods Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text-input.md Provides methods for imperative control over a TextInput component, such as setting and getting the cursor position. ```APIDOC ## set_cursor_offset ### Description Sets the cursor position to a specific byte offset within the text input. ### Method `set_cursor_offset(&mut self, offset: usize)` ### Parameters #### Path Parameters - **offset** (`usize`) - Required - Cursor position in bytes (not characters) ### Request Example ```rust handle.write().set_cursor_offset(0); ``` ``` ```APIDOC ## cursor_offset ### Description Gets the current cursor position in bytes. ### Method `cursor_offset(&self) -> usize` ### Returns - **usize** - The cursor offset ### Response Example ```rust let position = handle.read().cursor_offset(); ``` ``` -------------------------------- ### Build UI with element! Macro Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/00-START-HERE.md Demonstrates the basic usage of the `element!` macro to create and print a simple UI element containing text. ```rust element!(View { Text(content: "Hello") }).print(); ``` -------------------------------- ### Button with Mutable State Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-button.md Demonstrates using a button to modify mutable state within a component, such as incrementing a counter. ```rust use iocraft::prelude::*; #[component] fn Counter(mut hooks: Hooks) -> impl Into> { let mut count = hooks.use_state(|| 0); element! { View(flex_direction: FlexDirection::Column, gap: 1) { Text(content: format!("Count: {}", count)) Button( handler: move |_| count += 1, has_focus: true, ) { View(border_style: BorderStyle::Round) { Text(content: "Increment") } } } } } ``` -------------------------------- ### Button with SystemContext Integration Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-button.md Shows how to integrate a button with the `SystemContext` to perform system-level actions, such as exiting the application. ```rust use iocraft::prelude::*; #[component] fn QuitButton(mut hooks: Hooks) -> impl Into> { element! { Button( handler: move |_| { let mut system = hooks.use_context_mut::(); system.exit(); }, has_focus: true, ) { Text(content: "Quit") } } } ``` -------------------------------- ### Render an Element to a Canvas Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md The Canvas is the rendering target. Elements are rendered to a Canvas, which can then be printed or displayed. This example renders a simple View with Text. ```rust let mut elem = element!(View { Text(content: "Hi") }); let canvas = elem.render(Some(80)); println!("{}", canvas); ``` -------------------------------- ### Configure Render Loop Options Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md Configures the render loop with various options like fullscreen, mouse capture, and output redirection. The `unstable-output-streams` feature must be enabled for `Output::Stderr`. ```rust element!(MyApp) .render_loop() .fullscreen() // Fullscreen mode .enable_mouse_capture() // Mouse in inline mode .disable_mouse_capture() // No mouse #[cfg(feature = "unstable-output-streams")] .output(Output::Stderr) // Render to stderr .await? ``` -------------------------------- ### Using Colors with element! Macro Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/canvas.md Demonstrates how to apply standard, RGB, and dark colors to `Text` elements within a `View` using the `element!` macro. Ensure `iocraft::prelude::*` is imported. ```rust use iocraft::prelude::*; element! { View(flex_direction: FlexDirection::Column, gap: 1) { Text(content: "Standard Red", color: Color::Red) Text(content: "RGB Color", color: Color::Rgb(255, 100, 50)) Text(content: "Dark Blue", color: Color::DarkBlue) } } ``` -------------------------------- ### Get Mutable Borrow of Ref Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Returns a mutable borrow of the value contained within the `Ref` wrapper. This allows exclusive write access. ```rust pub fn write(&mut self) -> RefMut ``` -------------------------------- ### Render Interactively with render_loop Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/00-START-HERE.md Shows how to initiate an interactive rendering loop for a UI application. This method allows for fullscreen display and asynchronous execution. ```rust element!(MyApp).render_loop().fullscreen().await? ``` -------------------------------- ### Get Immutable Borrow of Ref Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/types.md Returns an immutable borrow of the value contained within the `Ref` wrapper. This allows shared read access. ```rust pub fn read(&self) -> Ref ``` -------------------------------- ### Text Without Wrapping Example Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text.md Demonstrates TextWrap::NoWrap to prevent text from wrapping, which may lead to overflow if the content exceeds container width. ```rust use iocraft::prelude::*; element! { View(width: 20) { Text( content: "This text will overflow if too long", wrap: TextWrap::NoWrap, ) } } ``` -------------------------------- ### Create Reusable Components with #[component] Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/00-START-HERE.md Shows how to define a reusable UI component named `MyButton` using the `#[component]` macro. This component renders a 'Click' button and accepts `Hooks` as a parameter. ```rust #[component] fn MyButton(mut hooks: Hooks) -> impl Into> { element!(Button { Text(content: "Click") }) } ``` -------------------------------- ### Render Elements to Various Outputs Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md Demonstrates how to render an element to a Canvas, a plain string, stdout/stderr, a custom writer, or an interactive loop. Use these methods to display UI components or manage output streams. ```rust let mut element = element!(View { Text(content: "Hi") }); let canvas = element.render(Some(80)); ``` ```rust let text = element.to_string(); ``` ```rust element.print(); element.eprint(); ``` ```rust element.write(&mut buffer)?; element.write_to_is_terminal(&mut stdout)?; ``` ```rust element.render_loop().fullscreen().await?; element.render_loop().enable_mouse_capture().await?; ``` ```rust element.mock_terminal_render_loop(config) ``` -------------------------------- ### Add State with use_state Hook Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/00-START-HERE.md Illustrates how to manage component state using the `use_state` hook. This example initializes a mutable state variable `count` to 0. ```rust let mut count = hooks.use_state(|| 0); ``` -------------------------------- ### Text Component with Styling Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-text.md Illustrates how to apply various styles like color, weight, and decoration to the Text component. ```APIDOC ## Text Component with Styling ### Description This example demonstrates applying different styles to `Text` components, including color, font weight, and text decoration. ### Method `element!` macro with `Text` component and style properties ### Endpoint N/A (Component usage) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```rust use iocraft::prelude::*; element! { View(flex_direction: FlexDirection::Column, gap: 1) { Text( content: "Bold Blue Text", color: Color::Blue, weight: Weight::Bold, ) Text( content: "Underlined Red Text", color: Color::Red, decoration: TextDecoration::Underline, ) Text( content: "Italic Green Text", color: Color::Green, italic: true, ) Text( content: "Inverted Colors", invert: true, ) } } ``` ### Response N/A (Component rendering) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Import Prelude Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/README.md Imports all built-in components, exported types and traits, hook traits, macros, and re-exported types from dependencies. ```rust use iocraft::prelude::*; ``` -------------------------------- ### Implement Navigation Menu Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md Creates a navigation menu component that responds to Up and Down arrow key events to change the selected option. The `View` and `Text` components, along with `FlexDirection`, are assumed to be available. ```rust #[component] fn Menu(mut hooks: Hooks) -> impl Into> { let mut selected = hooks.use_state(|| 0); let options = vec!["Option 1", "Option 2", "Option 3"]; hooks.use_terminal_events(move |event| { match event { TerminalEvent::Key(KeyEvent { code: KeyCode::Up, .. }) => { selected.set(selected.get().saturating_sub(1)); } TerminalEvent::Key(KeyEvent { code: KeyCode::Down, .. }) => { selected.set((selected.get() + 1).min(options.len() - 1)); } _ => {} // Ignore other events } }); element! { View(flex_direction: FlexDirection::Column) { // Render options with highlighting } } } ``` -------------------------------- ### Define an Element with a View and Text Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/REFERENCE-SUMMARY.md Elements are uninstantiated components created using the `element!` macro. This example shows a View with a rounded border containing a Text element. ```rust let elem = element!(View(border_style: BorderStyle::Round) { Text(content: "Hello") }); ``` -------------------------------- ### Basic View Component Usage Source: https://github.com/ccbrown/iocraft/blob/main/_autodocs/api-reference/components-view.md Demonstrates the basic usage of the View component with common styling properties like border, dimensions, padding, background color, flex direction, and gap. This is suitable for general layout containers. ```rust use iocraft::prelude::*; element! { View( border_style: BorderStyle::Round, border_color: Color::Blue, width: 40, height: 10, padding: 1, background_color: Color::DarkGrey, flex_direction: FlexDirection::Column, gap: 1, ) { Text(content: "Title", color: Color::White, weight: Weight::Bold) Text(content: "Content goes here") Text(content: "Footer text") } } ```