From b74e320c7e9a311d9e66b5cd292fdb387cb1e434 Mon Sep 17 00:00:00 2001 From: Chris Brown <1731074+ccbrown@users.noreply.github.com> Date: Tue, 24 Sep 2024 00:36:26 -0400 Subject: [PATCH] expand documentation, add many more doc examples --- packages/iocraft/src/components/box.rs | 13 +++++++ .../src/components/context_provider.rs | 9 +++++ packages/iocraft/src/components/text.rs | 11 ++++++ packages/iocraft/src/components/text_input.rs | 34 +++++++++++++++++++ packages/iocraft/src/hooks/use_context.rs | 10 ++++++ packages/iocraft/src/hooks/use_future.rs | 6 ++++ packages/iocraft/src/hooks/use_output.rs | 6 ++++ packages/iocraft/src/hooks/use_state.rs | 6 ++++ .../iocraft/src/hooks/use_terminal_events.rs | 6 ++++ packages/iocraft/src/lib.rs | 2 +- packages/iocraft/src/props.rs | 17 ++++++++++ 11 files changed, 119 insertions(+), 1 deletion(-) diff --git a/packages/iocraft/src/components/box.rs b/packages/iocraft/src/components/box.rs index b7965af..26f5b99 100644 --- a/packages/iocraft/src/components/box.rs +++ b/packages/iocraft/src/components/box.rs @@ -156,6 +156,19 @@ pub struct BoxProps<'a> { } /// `Box` is your most fundamental building block for laying out and styling components. +/// +/// # Example +/// +/// ``` +/// # use iocraft::prelude::*; +/// # fn my_element() -> impl Into> { +/// element! { +/// Box(padding: 2, border_style: BorderStyle::Round) { +/// Text(content: "Hello!") +/// } +/// } +/// # } +/// ``` #[derive(Default)] pub struct Box { border_style: BorderStyle, diff --git a/packages/iocraft/src/components/context_provider.rs b/packages/iocraft/src/components/context_provider.rs index 6aa6ba4..2e8a762 100644 --- a/packages/iocraft/src/components/context_provider.rs +++ b/packages/iocraft/src/components/context_provider.rs @@ -11,6 +11,15 @@ pub struct ContextProviderProps<'a> { } /// `ContextProvider` is a component that provides a context to its children. +/// +/// Once a context is provided, it can be accessed by the children using the +/// [`UseContext`](crate::hooks::UseContext) hook. +/// +/// # Example +/// +/// ``` +#[doc = include_str!("../../examples/context.rs")] +/// ``` #[derive(Default)] pub struct ContextProvider; diff --git a/packages/iocraft/src/components/text.rs b/packages/iocraft/src/components/text.rs index 475238e..71bb66b 100644 --- a/packages/iocraft/src/components/text.rs +++ b/packages/iocraft/src/components/text.rs @@ -59,6 +59,17 @@ pub struct TextProps { } /// `Text` is a component that renders a text string. +/// +/// # Example +/// +/// ``` +/// # use iocraft::prelude::*; +/// # fn my_element() -> impl Into> { +/// element! { +/// Text(content: "Hello!") +/// } +/// # } +/// ``` #[derive(Default)] pub struct Text { style: CanvasTextStyle, diff --git a/packages/iocraft/src/components/text_input.rs b/packages/iocraft/src/components/text_input.rs index f3eef76..be9bdd9 100644 --- a/packages/iocraft/src/components/text_input.rs +++ b/packages/iocraft/src/components/text_input.rs @@ -26,6 +26,40 @@ pub struct TextInputProps { } /// `TextInput` is a component that can receive text input from the user. +/// +/// It will fill the available space and display the current value. Typically, you will want to +/// render it in a [`Box`] component of the desired text field size. +/// +/// # Example +/// +/// ``` +/// # use iocraft::prelude::*; +/// # #[component] +/// # fn FormField(mut hooks: Hooks) -> impl Into> { +/// let value = hooks.use_state(|| "".to_string()); +/// +/// element! { +/// Box( +/// border_style: BorderStyle::Round, +/// border_color: Color::Blue, +/// ) { +/// Box(width: 15) { +/// Text(content: "Input: ") +/// } +/// Box( +/// background_color: Color::DarkGrey, +/// width: 30, +/// ) { +/// TextInput( +/// has_focus: true, +/// value: value.to_string(), +/// on_change: move |new_value| value.set(new_value), +/// ) +/// } +/// } +/// } +/// # } +/// ``` #[derive(Default)] pub struct TextInput { value: String, diff --git a/packages/iocraft/src/hooks/use_context.rs b/packages/iocraft/src/hooks/use_context.rs index 35172e9..1294fbe 100644 --- a/packages/iocraft/src/hooks/use_context.rs +++ b/packages/iocraft/src/hooks/use_context.rs @@ -5,6 +5,16 @@ use std::{ }; /// `UseContext` provides methods for accessing context from a component. +/// +/// With the exception of [`SystemContext`](crate::SystemContext), which is always available, +/// contexts are provided via the [`ContextProvider`](crate::components::ContextProvider) +/// component. +/// +/// # Example +/// +/// ``` +#[doc = include_str!("../../examples/context.rs")] +/// ``` pub trait UseContext<'a> { /// Returns a reference to the context of the given type. /// diff --git a/packages/iocraft/src/hooks/use_future.rs b/packages/iocraft/src/hooks/use_future.rs index c77f34c..1d9512d 100644 --- a/packages/iocraft/src/hooks/use_future.rs +++ b/packages/iocraft/src/hooks/use_future.rs @@ -8,6 +8,12 @@ use std::{ /// `UseFuture` is a hook that allows you to spawn an async task which is bound to the lifetime of /// the component. +/// +/// # Example +/// +/// ```no_run +#[doc = include_str!("../../examples/counter.rs")] +/// ``` pub trait UseFuture { /// Spawns a future which is bound to the lifetime of the component. When the component is /// dropped, the future will also be dropped. diff --git a/packages/iocraft/src/hooks/use_output.rs b/packages/iocraft/src/hooks/use_output.rs index dc86334..8fe7681 100644 --- a/packages/iocraft/src/hooks/use_output.rs +++ b/packages/iocraft/src/hooks/use_output.rs @@ -7,6 +7,12 @@ use std::{ /// `UseOutput` is a hook that allows you to write to stdout and stderr from a component. The /// output will be appended to stdout or stderr, above the rendered component output. +/// +/// # Example +/// +/// ```no_run +#[doc = include_str!("../../examples/use_output.rs")] +/// ``` pub trait UseOutput { /// Gets handles which can be used to write to stdout and stderr. fn use_output(&mut self) -> (StdoutHandle, StderrHandle); diff --git a/packages/iocraft/src/hooks/use_state.rs b/packages/iocraft/src/hooks/use_state.rs index 94f216e..6831e00 100644 --- a/packages/iocraft/src/hooks/use_state.rs +++ b/packages/iocraft/src/hooks/use_state.rs @@ -11,6 +11,12 @@ use std::{ /// `UseState` is a hook that allows you to store state in a component. /// /// When the state changes, the component will be re-rendered. +/// +/// # Example +/// +/// ```no_run +#[doc = include_str!("../../examples/counter.rs")] +/// ``` pub trait UseState { /// Creates a new state with its initial value computed by the given function. /// diff --git a/packages/iocraft/src/hooks/use_terminal_events.rs b/packages/iocraft/src/hooks/use_terminal_events.rs index 37af573..ad843b6 100644 --- a/packages/iocraft/src/hooks/use_terminal_events.rs +++ b/packages/iocraft/src/hooks/use_terminal_events.rs @@ -6,6 +6,12 @@ use std::{ }; /// `UseTerminalEvents` is a hook that allows you to listen for user input such as key strokes. +/// +/// # Example +/// +/// ```no_run +#[doc = include_str!("../../examples/use_input.rs")] +/// ``` pub trait UseTerminalEvents { /// Defines a callback to be invoked whenever a terminal event occurs. fn use_terminal_events(&mut self, f: F) diff --git a/packages/iocraft/src/lib.rs b/packages/iocraft/src/lib.rs index 96bb3b2..a29fdb3 100644 --- a/packages/iocraft/src/lib.rs +++ b/packages/iocraft/src/lib.rs @@ -58,7 +58,7 @@ // Code is organized into modules primarily for the benefit of the maintainers. Types will be // re-exported in the root so that users of the library have a flat namespace to work with. // -// The exception is the models that represent collections of types, namely hooks and components. +// The exception is the modules that represent collections of types, namely hooks and components. // Those types will remain in their modules for the public API. mod canvas; diff --git a/packages/iocraft/src/props.rs b/packages/iocraft/src/props.rs index cfcb51b..b43914f 100644 --- a/packages/iocraft/src/props.rs +++ b/packages/iocraft/src/props.rs @@ -34,6 +34,23 @@ use std::marker::PhantomData; /// } /// ``` /// +/// Properties can be used by custom components like so: +/// +/// ``` +/// # use iocraft::prelude::*; +/// #[derive(Default, Props)] +/// struct GreetingProps<'a> { +/// name: &'a str, +/// } +/// +/// #[component] +/// fn Greeting<'a>(props: &GreetingProps<'a>) -> impl Into> { +/// element! { +/// Text(content: format!("Hello, {}!", props.name)) +/// } +/// } +/// ``` +/// /// # Safety /// /// This requires the type to be [covariant](https://doc.rust-lang.org/nomicon/subtyping.html). If