From c55bc0c170ba43a43c8ee83cafa319055343d01f Mon Sep 17 00:00:00 2001
From: StarToaster <startoaster23@gmail.com>
Date: Wed, 9 Nov 2022 20:16:25 -0500
Subject: [PATCH] More changes to the book and improvements to code quality
 using clippy!

---
 Cargo.toml                                    |   1 +
 book/src/SUMMARY.md                           |  12 +-
 book/src/chapter_2.md                         | 208 ++++++++----------
 book/src/chapter_3.md                         | 128 ++++++++++-
 book/src/chapter_4.md                         |  41 +++-
 book/src/chapter_5.md                         |  55 ++++-
 book/src/chapter_6.md                         |  17 ++
 book/src/chapter_7.md                         |  17 ++
 book/src/chapter_8.md                         |  62 ++++++
 book/src/chapter_9.md                         |   2 +
 book/src/img/kayak.svg                        |  62 ++++++
 book/src/img/parent-child.svg                 |   1 +
 book/src/img/prop-flow.svg                    |   1 +
 book/src/introduction.md                      |   5 +
 examples/bevy_scene.rs                        |   4 +-
 examples/clipping.rs                          |   2 +-
 examples/context.rs                           |  16 +-
 examples/demo.rs                              |   2 +-
 examples/image.rs                             |   2 +-
 examples/nine_patch.rs                        |   2 +-
 examples/simple_state.rs                      |   2 +-
 examples/tabs/tab.rs                          |   2 +-
 examples/tabs/tab_button.rs                   |   3 +-
 examples/tabs/tab_context.rs                  |   4 +-
 examples/text.rs                              |   4 +-
 examples/texture_atlas.rs                     |   4 +-
 examples/todo/input.rs                        |   2 +-
 examples/todo/items.rs                        |   2 +-
 examples/todo/todo.rs                         |   6 +
 examples/vec.rs                               |   6 +-
 kayak_font/src/atlas.rs                       |   4 +-
 .../src/bevy/renderer/font_texture_cache.rs   |  10 +-
 kayak_font/src/font.rs                        |   8 +-
 kayak_ui_macros/src/widget.rs                 |   6 +-
 kayak_ui_macros/src/widget_attributes.rs      |   4 +-
 src/calculate_nodes.rs                        |  10 +-
 src/camera/camera.rs                          |   6 +
 src/children.rs                               |   8 +-
 src/context.rs                                |  61 +++--
 src/context_entities.rs                       |   2 +-
 src/event.rs                                  |  14 +-
 src/event_dispatcher.rs                       |   9 +-
 src/focus_tree.rs                             |   8 +-
 src/layout_dispatcher.rs                      |   1 -
 src/node.rs                                   |  24 +-
 src/render/font/font_mapping.rs               |  23 +-
 src/render/nine_patch/extract.rs              |   7 +-
 src/render/texture_atlas/extract.rs           |   7 +-
 src/render/unified/mod.rs                     |   2 +-
 src/render/unified/pipeline.rs                |   8 +-
 src/styles/corner.rs                          |   2 +-
 src/styles/edge.rs                            |   2 +-
 src/styles/options_ref.rs                     |   2 +-
 src/styles/style.rs                           |   6 +-
 src/tree.rs                                   |  75 +++----
 src/widget.rs                                 |   2 +-
 src/widget_context.rs                         |   6 +-
 src/widget_state.rs                           |  13 +-
 src/widgets/app.rs                            |   2 +-
 src/widgets/background.rs                     |   2 +-
 src/widgets/button.rs                         |   2 +-
 src/widgets/clip.rs                           |   2 +-
 src/widgets/element.rs                        |   6 +-
 src/widgets/image.rs                          |   2 +-
 src/widgets/scroll/scroll_box.rs              |  13 +-
 src/widgets/scroll/scroll_content.rs          |   2 +-
 src/widgets/scroll/scroll_context.rs          |   2 +-
 src/widgets/text_box.rs                       |   2 +-
 src/widgets/window.rs                         |   6 +-
 src/widgets/window_context_provider.rs        |   6 +-
 70 files changed, 685 insertions(+), 367 deletions(-)
 create mode 100644 book/src/chapter_6.md
 create mode 100644 book/src/chapter_7.md
 create mode 100644 book/src/chapter_8.md
 create mode 100644 book/src/chapter_9.md
 create mode 100644 book/src/img/kayak.svg
 create mode 100644 book/src/img/parent-child.svg
 create mode 100644 book/src/img/prop-flow.svg

diff --git a/Cargo.toml b/Cargo.toml
index b80a8c0..7f0f7fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,6 +20,7 @@ indexmap = "1.9"
 log = "0.4"
 bitflags = "1.3.2"
 reorder = "2.1"
+resources = "1.1"
 
 [dev-dependencies]
 fastrand = "1.8"
diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
index 1679120..0402587 100644
--- a/book/src/SUMMARY.md
+++ b/book/src/SUMMARY.md
@@ -2,7 +2,11 @@
 
 - [Introduction](./introduction.md)
 - [Chapter 1 - Installing and hello world!](./chapter_1.md)
-- [Chapter 2 - Creating custom widgets!](./chapter_2.md)
-- [Chapter 3 - State](./chapter_3.md)
-- [Chapter 4 - Context](./chapter_4.md)
-- [Chapter 5 - Fonts](./chapter_5.md)
\ No newline at end of file
+- [Chapter 2 - Understanding flow](./chapter_2.md)
+- [Chapter 3 - Creating custom widgets!](./chapter_3.md)
+- [Chapter 4 - State](./chapter_4.md)
+- [Chapter 5 - Context](./chapter_5.md)
+- [Chapter 6 - Fonts](./chapter_6.md)
+- [Chapter 7 - Widget Update Systems(Diffing)](./chapter_7.md)
+- [Chapter 8 - Prebuilt Widgets](./chapter_8.md)
+- [Chapter 9 - Practical Usage](./chapter_9.md)
\ No newline at end of file
diff --git a/book/src/chapter_2.md b/book/src/chapter_2.md
index 256b25e..8782e06 100644
--- a/book/src/chapter_2.md
+++ b/book/src/chapter_2.md
@@ -1,127 +1,107 @@
-# Chapter 2 - Creating custom widgets!
-Kayak UI allows users to create custom widgets.
-
-Widgets are structured in a few different ways:
-1. Widgets at a bare minimum must include a Props component, Widget Bundle, and the update and render systems.
-2. Widgets can include custom components and data but the default `widget_update` system only supports diffing of props and state.
-3. Widgets have some base components which are auto checked these are: KStyles and KChildren.
-
-I think it's best if we showcase a simple example:
+# Chapter 2 - Understanding flow
+In Kayak widget structure and flow are important concepts. In this section we'll be discussion high level concepts on how Kayak UI works.
+
+Kayak UI builds out UI using a tree structure. A widget can be defined as any object that lives in the UI tree. Typically a widget will have some sort of visual appearance, however that doesn't necessarily have to be the case. You might have widgets that manage state or just wrap other widgets.
+
+## Core Concepts
+
+### Widgets are entities
+Kayak UI uses Bevy ECS. Each widget is considered an entity with a collection of data. Typically an widget and it's entity can contain whatever data desired, but some common components are:
+- Mount - A component tag used to know that a widget was spawned and added to the tree.
+- KStyle - Used to describe how a widget looks. Kayak uses this component to dictate UI rendering.
+- KChildren - A collection of entities that are added to the tree in a deferred way. These entities are coming from higher up the hierarchy. 
+- OnEvent - A mini/micro bevy system that lets you respond to UI input events.
+- OnChange - A mini/micro system which allows changes to state based on value changes to state. 
+- OnLayout - A mini/micro system which allows reaction to layout change events. I.E. the width, height, or position has changed.
+- Focusable - Lets the event dispatcher know that this widget can be focused.
+- WidgetName - All widgets require this component for internal purposes. This is essentially used to determine the "type" of a widget.
+
+### Widgets and bundles?
+It's advised to have bundles that correspond to a group of components on a widget. Example:
 ```rust
-// At a bare minimum the widget props component must include these derives. 
-// This is because we need to diff the previous values of these.
-// Default is used to make creating widgets a little easier.
-// And component is required since this is a bevy component!
-[#derive(Component, Clone, PartialEq, Default)]
-pub struct MyButtonProps {
-
-}
-
-// In the future this will tell Kayak that these Props belongs to a widget.
-// For now it's use to get the `WidgetName` component.
-impl Widget for MyButtonProps { }
-
-// Now we need a widget bundle this can represent a collection of components our widget might have
-// Note: You can include custom data here. Just don't expect it to get diffed during update!
 #[derive(Bundle)]
-pub struct MyButtonBundle {
-    pub props: MyButtonProps,
+pub struct BackgroundBundle {
+    pub background: Background,
     pub styles: KStyle,
     pub children: KChildren,
-    // This allows us to hook into on click events!
     pub on_event: OnEvent,
-    // Widget name is required by Kayak UI!
     pub widget_name: WidgetName,
 }
-
-impl Default for MyButtonBundle {
-    fn default() -> Self {
-        Self {
-            props: MyButtonProps::default(),
-            styles: KStyle::default(),
-            children: KChildren::default(),
-            on_event: OnEvent::default(),
-            // Kayak uses this component to find out more information about your widget.
-            // This is done because bevy does not have the ability to query traits.
-            widget_name: MyButtonProps::default().get_name(),
+```
+Bundles are also required when using the RSX syntax:
+```rust
+rsx! {
+    <BackgroundBundle
+        styles: KStyle {
+            background_color: Color::rgba(1.0, 1.0, 1.0, 1.0).into(),
+            ..Default::default()
         }
-    }
+    />
 }
+```
+In the example above the RSX macro automatically adds missing fields in the bundle using rust default and the spread operator: `..Default::default()`. Because of this requirement users who want to use RSX need to also implement default on their bundles.
 
-// Now we need to create our systems.
-// Since our button doesn't have any custom data we can diff using the default widget_update system.
-// We do need to create a render system!
-
-pub fn my_button_render(
-    // This is a bevy feature which allows custom parameters to be passed into a system.
-    // In this case Kayak UI gives the system a `KayakWidgetContext` and an `Entity`.
-    In((mut widget_context, entity)): In<(KayakWidgetContext, Entity)>,
-    // The rest of the parameters are just like those found in a bevy system!
-    // In fact you can add whatever you would like here including more queries or lookups
-    // to resources within bevy's ECS.
-    mut commands: Commands,
-    // In this case we really only care about our buttons children! Let's query for them.
-    mut query: Query<&KChildren>,
-) {
-    // Grab our children for our button widget:
-    if let Ok(children) = query.get(entity) {
-
-        let background_styles = KStyle {
-            // Lets use red for our button background!
-            background_color: StyleProp::Value(Color::RED),
-            // 50 pixel border radius.
-            border_radius: Corner::all(50.0).into(),
-            ..Default::default()
-        };
+### Spawning Widgets
+Widgets can be spawned using bevy's default spawning method. Example:
+```rust
+commands.spawn(MyWidgetBundle { .. });
+```
 
-        rsx! {
-            <BackgroundBundle
-                // We pass the children to the background bundle!
-                children={children.clone()}
-            />
-        }
-    }
+However, it is advised that you use the `WidgetContext`'s `spawn_widget` function. This function caches entities at a specific spot in the tree. Take this tree for example:
+```
+widget1 - entity 2
+    - widget2 entity 3
+    - widget3 entity 4
+```
+When widget 1 renders it's children will have random entity id's if you use bevy's default spawning commands, but by using `spawn_widget` you can guarantee somewhat consistent entities. There are a couple of a caveats to this though. If a widget is despawned due to being removed from the tree it's entity id is no longer guaranteed. This means that entities that are removed from the tree will lose access to their context and state. It's important to remember that!
 
-    // The boolean returned here tells kayak UI to update the tree. You can avoid tree updates by
-    // returning false, but in practice this should be done rarely. As kayak diff's the tree and
-    // will avoid tree updates if nothing has changed! 
-    true
-}
+### Relationships
 
-// Finally we need to let the core widget context know about our new widget!
-fn startup(...) {
-
-    // Default kayak startup stuff.
-    ...
-
-    // We need to register the prop and state types.
-    // State is empty so you can use the `EmptyState` component!
-    context.add_widget_data::<MyButtonProps, EmptyState>();
-
-    // Next we need to add the systems
-    context.add_widget_system(
-        // We are registering these systems with a specific WidgetName.
-        MyButtonProps::default().get_name(),
-        // widget_update auto diffs props and state.
-        // Optionally if you have context you can use: widget_update_with_context
-        // otherwise you will need to create your own widget update system!
-        widget_update::<MyButtonProps, EmptyState>,
-        // Add our render system!
-        my_button_render,
-    );
-
-    // We can now create our widget like:
-    rsx! {
-        <KayakAppBundle>
-            <MyButtonBundle>
-                <TextWidgetBundle
-                    text={TextProps {
-                        content: "Click me!".into(),
-                        ..Default::default()
-                    }}
-                />
-            </MyButtonBundle>
-        </KayakAppBundle>
-    } 
-} 
-```
+Widgets, by the nature of them being stored as a tree, contain certain relationships. The most common one is the *
+parent-child* relationship. A widget may contain zero or more children.
+
+<p align="center">
+  <img alt="Diagram showing the parent-child relationship" src="img/parent-child.svg" />
+</p>
+
+When a parent re-renders, it also causes its children to be re-rendered as well (more on this later).
+
+Another implicit relationship is that of siblings. These aren't currently very useful in Kayak UI currently, but know that any time two widgets share a parent, they are considered siblings.
+
+### Props
+
+What good is a widget if it can't hold or process data? This is where the concept of *props* comes in (short for "
+properties"). Props allow data to flow from parent to child.
+
+<p align="center">
+  <img alt="Diagram showing the flow of props" src="img/prop-flow.svg" />
+</p>
+
+For example, a widget might have access to a game's player info. It could then take the current value of the player's
+health points and pass that to a widget that is specifically configured to display health points. Which brings up
+another important topic when talking about widgets: modularity.
+
+### Modularity
+
+Widgets are meant to be modular. It's rarely a good idea to have a widget with hundreds and hundreds of lines of code.
+Kayak UI instead suggests breaking parts of your UI down into individual components. This could be as simple as breaking up logical parts of a single UI into multiple files in order to make things easier to read/maintain.
+
+This modularity allows for widgets to be abstracted to cover more generic use-cases. Rather than having two different
+widgets for a player's health points and a teammates, you could just create one reusable `Health` widget. Want to keep
+the same functionality but modify the style for enemies? Wrap the `Health` widget in another widget that configures it
+enough to fit your needs.
+
+### State
+
+To make widgets even more modular, provide greater functionality, and be reactive, widgets may contain their own state. While props can be used to pass data to widgets, state allows data to be retained. This is important because non-state data, such as props, are lost between renders. Without state, what goes in is all the widget has at its disposal.
+
+This book has a [section](./chapter_4.md) dedicated to widget state so check that out for more on state!
+
+### Lifecycle
+The last core concept is that of *widget lifecycle*. Widgets have a lifecycle as entities which looks something like this:
+
+1. Mount - This occurs when a widget is added to the tree for the first time. A component is added called `Mount` and is removed after the first render.
+2. Update or Diff - During each update loop the widgets are diffed with previous values from the last update to see if they have changed. If a widget has changed it is re-rendered.
+3. Render - Render occurs when a widget has changed and allows users to change behavior according to entity changes.
+4. Layout - Occurs after the entire tree has been updated. Widget entities marked as "dirty" will have their rendering and layout recalculated.
+5. Removal/Despawning - Entities that are removed from the tree are despawned additionally any children they had are also despawned and removed from the tree. It's important to avoid removing a widget from the tree if you need to preserve that widgets state.
\ No newline at end of file
diff --git a/book/src/chapter_3.md b/book/src/chapter_3.md
index e3248f6..256b25e 100644
--- a/book/src/chapter_3.md
+++ b/book/src/chapter_3.md
@@ -1 +1,127 @@
-# Chapter 3 - State
+# Chapter 2 - Creating custom widgets!
+Kayak UI allows users to create custom widgets.
+
+Widgets are structured in a few different ways:
+1. Widgets at a bare minimum must include a Props component, Widget Bundle, and the update and render systems.
+2. Widgets can include custom components and data but the default `widget_update` system only supports diffing of props and state.
+3. Widgets have some base components which are auto checked these are: KStyles and KChildren.
+
+I think it's best if we showcase a simple example:
+```rust
+// At a bare minimum the widget props component must include these derives. 
+// This is because we need to diff the previous values of these.
+// Default is used to make creating widgets a little easier.
+// And component is required since this is a bevy component!
+[#derive(Component, Clone, PartialEq, Default)]
+pub struct MyButtonProps {
+
+}
+
+// In the future this will tell Kayak that these Props belongs to a widget.
+// For now it's use to get the `WidgetName` component.
+impl Widget for MyButtonProps { }
+
+// Now we need a widget bundle this can represent a collection of components our widget might have
+// Note: You can include custom data here. Just don't expect it to get diffed during update!
+#[derive(Bundle)]
+pub struct MyButtonBundle {
+    pub props: MyButtonProps,
+    pub styles: KStyle,
+    pub children: KChildren,
+    // This allows us to hook into on click events!
+    pub on_event: OnEvent,
+    // Widget name is required by Kayak UI!
+    pub widget_name: WidgetName,
+}
+
+impl Default for MyButtonBundle {
+    fn default() -> Self {
+        Self {
+            props: MyButtonProps::default(),
+            styles: KStyle::default(),
+            children: KChildren::default(),
+            on_event: OnEvent::default(),
+            // Kayak uses this component to find out more information about your widget.
+            // This is done because bevy does not have the ability to query traits.
+            widget_name: MyButtonProps::default().get_name(),
+        }
+    }
+}
+
+// Now we need to create our systems.
+// Since our button doesn't have any custom data we can diff using the default widget_update system.
+// We do need to create a render system!
+
+pub fn my_button_render(
+    // This is a bevy feature which allows custom parameters to be passed into a system.
+    // In this case Kayak UI gives the system a `KayakWidgetContext` and an `Entity`.
+    In((mut widget_context, entity)): In<(KayakWidgetContext, Entity)>,
+    // The rest of the parameters are just like those found in a bevy system!
+    // In fact you can add whatever you would like here including more queries or lookups
+    // to resources within bevy's ECS.
+    mut commands: Commands,
+    // In this case we really only care about our buttons children! Let's query for them.
+    mut query: Query<&KChildren>,
+) {
+    // Grab our children for our button widget:
+    if let Ok(children) = query.get(entity) {
+
+        let background_styles = KStyle {
+            // Lets use red for our button background!
+            background_color: StyleProp::Value(Color::RED),
+            // 50 pixel border radius.
+            border_radius: Corner::all(50.0).into(),
+            ..Default::default()
+        };
+
+        rsx! {
+            <BackgroundBundle
+                // We pass the children to the background bundle!
+                children={children.clone()}
+            />
+        }
+    }
+
+    // The boolean returned here tells kayak UI to update the tree. You can avoid tree updates by
+    // returning false, but in practice this should be done rarely. As kayak diff's the tree and
+    // will avoid tree updates if nothing has changed! 
+    true
+}
+
+// Finally we need to let the core widget context know about our new widget!
+fn startup(...) {
+
+    // Default kayak startup stuff.
+    ...
+
+    // We need to register the prop and state types.
+    // State is empty so you can use the `EmptyState` component!
+    context.add_widget_data::<MyButtonProps, EmptyState>();
+
+    // Next we need to add the systems
+    context.add_widget_system(
+        // We are registering these systems with a specific WidgetName.
+        MyButtonProps::default().get_name(),
+        // widget_update auto diffs props and state.
+        // Optionally if you have context you can use: widget_update_with_context
+        // otherwise you will need to create your own widget update system!
+        widget_update::<MyButtonProps, EmptyState>,
+        // Add our render system!
+        my_button_render,
+    );
+
+    // We can now create our widget like:
+    rsx! {
+        <KayakAppBundle>
+            <MyButtonBundle>
+                <TextWidgetBundle
+                    text={TextProps {
+                        content: "Click me!".into(),
+                        ..Default::default()
+                    }}
+                />
+            </MyButtonBundle>
+        </KayakAppBundle>
+    } 
+} 
+```
diff --git a/book/src/chapter_4.md b/book/src/chapter_4.md
index e7ee814..58e8a24 100644
--- a/book/src/chapter_4.md
+++ b/book/src/chapter_4.md
@@ -1 +1,40 @@
-# Chapter 4 - Context
+# Chapter 3 - State
+State is data that is directly associated with a particular widget. State persists during re-renders, but will be destroyed when an widget is despawned.
+
+State can be created in Kayak easily, here is an example:
+```rust
+#[derive(Component, Default, PartialEq, Clone)]
+struct CurrentCountState {
+    foo: u32,
+}
+
+// During a widget's render function
+let state_entity = widget_context.use_state(
+    // Bevy commands
+    &mut commands,
+    // The widget entity.
+    entity,
+    // The default starting values for the state.
+    CurrentCountState::default()
+);
+
+// State can be queried like any entity.
+// This can be done via bevy query iteration or via lookup using the state_entity
+if let Ok(state) = state_query.get(state_entity) {
+    dbg!(state.foo);
+}
+
+fn my_bevy_system(state_query: Query<&CurrentCountState>) {
+    for state in state_query.iter() {
+        dbg!(state.foo);
+    }
+}
+```
+
+When an entity is despawned the state associated with that entity is also despawned.
+
+## Update/Diffing system
+By default Kayak provides a system for diffing widgets. This system is called: `widget_update` and can be attached to any widget via the root kayak context.
+
+`widget_update` takes two generic parameters called: `Props` and `State`. Both of these types expect to derive: `Component`, `PartialEq`, and `Clone`. Currently only one state type can be defined which can be an issue as widgets might have more than one piece of state. For now it's advised to group state by component type, however if a user desires they can implement a custom widget update system which manually checks more pieces of state. This is however considered to be more advanced usage and may not be as well documented.
+
diff --git a/book/src/chapter_5.md b/book/src/chapter_5.md
index 7581bf6..258575e 100644
--- a/book/src/chapter_5.md
+++ b/book/src/chapter_5.md
@@ -1,17 +1,48 @@
-# Chapter 5 - Fonts
-Kayak UI uses SDF(signed distance fields) for rendering fonts. More specifically it uses multi-channel signed distance fields. Reasons for why we use MSDF:
-- High Quality font rendering.
-- Fast rendering!
-- No need for a new asset for each font size. MSDF's can size to any font size!
+# Chapter 4 - Context
+Context in Kayak UI allows users to pass data through the widget tree without having to pass data between each widget at every level in the tree.
 
-Font's are stored as an atlased image and a json file which tells Kayak about the font glyphs. Check out `roboto.kayak_font` and `roboto.png` in the `assets` folder.
+Typically in Kayak the data is passed top-down or parent to child via "props", but this can be cumbersome when dealing with complex widget trees. Context provides a way to share values from a parent widget down to children without the need to explicitly pass that data through every level of the tree.
 
-## Generating new fonts.
-In order to create a new font you need to use the `msdf-atlas-gen` tool. This can be found at:
-[https://github.com/Chlumsky/msdf-atlas-gen](https://github.com/Chlumsky/msdf-atlas-gen)
+## When to use context?
+Context can be great for sharing "global" data. This might be something as simple as a user or potentially even more complex data. In the [tabs example](../../examples/tabs/tabs.rs) we can see how context is used to pass shared tab state to the buttons and the button content.
 
-Please refer to the documentation found in the link about for generating fonts. However a simple way is to use the following command line:
 
+## How to use context?
+Context starts by creating a context entity that is associated with a piece of data and it's parent widget. This looks like:
+```rust
+// Check if the context entity already exists
+if widget_context
+    .get_context_entity::<MyContext>(entity)
+    .is_none()
+{
+    // Spawn the context entity with initial state
+    let context_entity = commands
+        .spawn(MyContext {
+            foo: 0,
+        })
+        .id();
+
+    // Let the widget context know about our custom context data.
+    widget_context.set_context_entity::<MyContext>(Some(entity), context_entity);
+}
+```
+
+Once the context has been created users can query the context in widget render systems like so:
+```rust
+fn my_child_widget_render(
+    ...
+    context_query: Query<&MyContext>,
+) {
+    // get_context_entity will jump up the tree until it finds a matching data type and entity.
+    if let Some(context_entity) = widget_context.get_context_entity::<MyContext>(entity) {
+        let context_data = context_query.get(context_entity);
+        dbg!(context_data.foo);
+    }
+}
 ```
-.\msdf-atlas-gen.exe -font .\my_font.ttf -type msdf -minsize 32 -format png -imageout my_font.png -json my_font.kayak_font
-```
\ No newline at end of file
+
+## Handling diff and widget updating
+When a widget is associated with context it's important that the widget update system is aware of this. By default the `widget_update` diff system is used. This accepts types for props and state but not for context. A separate system called `widget_update_with_context` can be used which takes an optional third type for context.
+
+### Important!
+`widget_update_with_context` is only designed to work with one type of context. If you need multiple context diffing for a single widget it's advised that you use a custom widget update system.
\ No newline at end of file
diff --git a/book/src/chapter_6.md b/book/src/chapter_6.md
new file mode 100644
index 0000000..7581bf6
--- /dev/null
+++ b/book/src/chapter_6.md
@@ -0,0 +1,17 @@
+# Chapter 5 - Fonts
+Kayak UI uses SDF(signed distance fields) for rendering fonts. More specifically it uses multi-channel signed distance fields. Reasons for why we use MSDF:
+- High Quality font rendering.
+- Fast rendering!
+- No need for a new asset for each font size. MSDF's can size to any font size!
+
+Font's are stored as an atlased image and a json file which tells Kayak about the font glyphs. Check out `roboto.kayak_font` and `roboto.png` in the `assets` folder.
+
+## Generating new fonts.
+In order to create a new font you need to use the `msdf-atlas-gen` tool. This can be found at:
+[https://github.com/Chlumsky/msdf-atlas-gen](https://github.com/Chlumsky/msdf-atlas-gen)
+
+Please refer to the documentation found in the link about for generating fonts. However a simple way is to use the following command line:
+
+```
+.\msdf-atlas-gen.exe -font .\my_font.ttf -type msdf -minsize 32 -format png -imageout my_font.png -json my_font.kayak_font
+```
\ No newline at end of file
diff --git a/book/src/chapter_7.md b/book/src/chapter_7.md
new file mode 100644
index 0000000..794420f
--- /dev/null
+++ b/book/src/chapter_7.md
@@ -0,0 +1,17 @@
+# Chapter 7 - Widget Update Systems(Diffing)
+By default Kayak offers two widget update systems. These systems look at components on widgets and automatically diff(compare) them to the same components from the last render. If the widgets have changed it causes the internal systems to call that widget's render function.
+
+The default widget update systems are:
+- `widget_update<Props, State>` - This system diffs the props and state components. It also diffs some commonly provided components like: `KStyle` and `KChildren` automatically. Note: Only one type of state is allowed. In the future it might be possible to pass in a tuple of state types instead. If you require multiple state "types" please create a custom widget update function.
+- `widget_update_with_context<Props, State, Context>` - Like `widget_update` but also provides functionality for auto diffing context as well. Again like with state this will only auto check one singular context type. 
+
+## How does it work?
+Behind the scenes Kayak UI keeps track of the types that are associated with props and state for a given widget. After each successful render of a widget kayak will clone the entire widget onto a new entity. This is considered the "last" render state of the entity and is expect to not change. These special entities can be avoided by using the `PreviousWidget` tag component and bevy query filters. They are also not added to the tree and are only loosely attached to the widget entity that lives in the tree.
+
+## Custom widget update systems
+Since the widget update is a system users can define very fine grained and custom diffing by writing their own system.
+
+Kayak UI provides a bevy `SystemParam` called `WidgetParam` which aids in achieving this. The `SystemParam` takes two generics like the default widget update system for props and state. It has a special function which compares the components from entity A with entity B called `has_changed`.
+
+## **WARNING!** - There is currently little documentation for how this works, and this is considered a rather delicate and highly advanced operation. 
+Feel free to reach out if you feel like you would like to help improve this API!
\ No newline at end of file
diff --git a/book/src/chapter_8.md b/book/src/chapter_8.md
new file mode 100644
index 0000000..e83d1d3
--- /dev/null
+++ b/book/src/chapter_8.md
@@ -0,0 +1,62 @@
+# Chapter 8 - Prebuilt Widget
+Kayak UI comes with a few pre-built widgets. Some of these widgets are highly customizable and others might be more rigidly defined. 
+
+## 1. Core Visual Widgets
+Core visual widgets are widgets that provide specific rendering commands to the rendering backend. These drive the look and feel of Kayak UI!
+
+### Background
+A background is a widget that renders a quad. It's style render command is hard coded to always be `RenderCommand::Quad`. In addition to rendering a quad the background widget can be customized to render a border, border radius, and other similar affects.
+
+#### Props:
+- KStyle
+- KChildren 
+- OnEvent
+
+### Clip
+Clips are special widgets that cause areas of the renderer to not draw pixels outside of their bounds. These can essentially be considered an inverse "mask" although they are always only rectangular in shape. A clip can be useful to keep content from spilling out of an existing area, in that regard they almost behave like the CSS overflow property.
+
+#### Props:
+- KStyle
+- KChildren
+
+### Image
+Like the name implies this widget renders an image. The image that is rendered is an image loaded in by bevy. The size is controlled by styles. The widget also responds to border radius via an SDF mask.
+
+#### Props:
+- KImage(Handle<Image>) - This component accepts a bevy handle to an image asset.
+- KStyle
+
+### Nine Patch
+The nine patch widget is a special widget designed to render a sliced UI image. Also know as 9-slicing. This 2D technique allows users to render UI images at multiple resolutions while maintaining a level of quality. The image in the middle is repeated.
+
+#### Props:
+- NinePatch
+    - `handle`: A bevy handle to a nine patch image asset which.
+    - `border`: This represents the area that is sliced into eight pieces along the edge of the image. The ninth piece is the middle which is repeated.
+- KStyle
+- KChildren
+
+### Text
+This widget renders text directly to the screen.
+
+#### Props:
+- TextProps
+    - `content`: The string to display
+    - `font`: The name of the font to use 
+    - `line_height`: The height of a line of text (currently in pixels). Defaults to font size * 1.2 which is the firefox default method of calculating line height.
+    - `show_cursor`: If true, displays the default text cursor when hovered.
+    - `size`: The font size (in pixels)
+    - `alignement`: Text alignment.
+    - `user_styles`: Specific styles applied directly to the text itself.
+    - `word_wrap`: Wraps the words if said text would overflow it's parent.
+- KStyle
+
+### Texture Atlas
+The texture atlas widget will render a bevy texture atlas inside of the UI. This can be useful for users who have UI that lives inside of an atlas texture. Although currently there are not any performance benefits of using this compared to just a regular single image.
+
+#### Props
+- TextureAtlasProps
+    - `handle`: The handle to bevy texture atlas image
+    - `position`: The position of the tile (in pixels)
+    - `tile_size`: The size of the tile (in pixels)
+- KStyle
diff --git a/book/src/chapter_9.md b/book/src/chapter_9.md
new file mode 100644
index 0000000..d88803d
--- /dev/null
+++ b/book/src/chapter_9.md
@@ -0,0 +1,2 @@
+# Chapter 9 - Practical Usage
+Coming soon!
\ No newline at end of file
diff --git a/book/src/img/kayak.svg b/book/src/img/kayak.svg
new file mode 100644
index 0000000..9231eef
--- /dev/null
+++ b/book/src/img/kayak.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="400px"
+   height="auto"
+   viewBox="0 0 105.15361 35.339237"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+   sodipodi:docname="drawing.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#000000"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0"
+     inkscape:pagecheckerboard="0"
+     inkscape:document-units="mm"
+     showgrid="false"
+     inkscape:zoom="3.0003928"
+     inkscape:cx="234.80259"
+     inkscape:cy="44.160884"
+     inkscape:window-width="1920"
+     inkscape:window-height="1027"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <defs
+     id="defs2">
+    <linearGradient
+       id="linearGradient1220"
+       inkscape:swatch="solid">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop1218" />
+    </linearGradient>
+  </defs>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-34.545261,-95.557219)">
+    <path
+       id="path5390"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssscccccccccc"
+       style="opacity:1;mix-blend-mode:lighten;fill:#000000;stroke:#ffffff;stroke-width:0.555625;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:2.3;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
+       d="m 106.97339,95.844462 c -0.22224,-0.03308 -0.44794,0.04183 -0.66913,0.08138 -0.23785,0.04253 -0.53727,-0.0063 -0.70528,0.167277 -0.14758,0.152485 -0.014,0.444024 -0.12659,0.623914 -0.15798,0.252442 -0.4971,0.334116 -0.70982,0.542528 -0.18996,0.186132 -0.42021,0.369385 -0.49731,0.623914 -0.093,0.306864 0.0816,0.637831 0.0814,0.95848 0,0.473445 -0.18325,0.945621 -0.12206,1.415095 0.042,0.32237 0.22627,0.60968 0.33004,0.91779 0.0882,0.26198 0.0757,0.57555 0.24865,0.79118 0.12083,0.15061 0.38656,0.13443 0.50184,0.28935 0.14509,0.19503 0.13922,0.46834 0.16728,0.7098 0.024,0.20658 0.12516,0.45781 0,0.62391 -0.12171,0.16153 -0.38137,0.17978 -0.58322,0.16728 -0.21093,-0.0131 -0.38986,-0.33395 -0.58322,-0.24865 -0.22938,0.10117 -0.15034,0.47918 -0.24866,0.70979 -0.0484,0.11346 -0.0731,0.25044 -0.16728,0.33004 -0.17841,0.15074 -0.46296,0.0982 -0.66913,0.20797 -0.15704,0.0836 -0.2777,0.22254 -0.41592,0.33457 -0.22219,0.18004 -0.44953,0.35407 -0.66461,0.54253 -0.25821,0.22623 -0.58002,0.4073 -0.75049,0.70527 -0.15577,0.27228 -0.12339,0.61571 -0.20798,0.91779 -0.0832,0.29691 -0.21986,0.57777 -0.29388,0.87709 -0.081,0.32758 -0.10406,0.66686 -0.16275,0.99915 -0.0392,0.22208 -0.0356,0.45823 -0.12659,0.6646 -0.0842,0.19113 -0.25295,0.33253 -0.37526,0.50184 -0.12802,0.17724 -0.290515,0.33644 -0.375235,0.538 -0.08798,0.20926 -0.105396,0.44313 -0.126589,0.66914 -0.01302,0.13804 0.0822,0.30429 0,0.41592 -0.111358,0.15123 -0.386081,0.0569 -0.538004,0.16728 -0.137311,0.0998 -0.14858,0.32814 -0.293873,0.41593 -0.275828,0.16665 -0.639445,0.0809 -0.95848,0.12659 -0.26416,0.0378 -0.525859,0.0935 -0.791183,0.12206 -0.220686,0.0237 -0.443865,0.0639 -0.664607,0.0407 -0.258172,-0.0271 -0.492231,-0.18174 -0.750491,-0.20796 -0.220903,-0.0224 -0.456141,-0.0313 -0.66458,0.0452 -0.307605,0.11283 -0.561472,0.34959 -0.791184,0.58322 -0.202313,0.20573 -0.451855,0.42111 -0.501835,0.70527 -0.01762,0.10011 0.145889,0.21531 0.08139,0.29387 -0.838994,1.02201 -2.722033,0.18107 -3.95605,-0.29387 -0.295698,-0.1138 -0.465931,-0.72247 -0.750491,-0.58322 -0.124536,0.0609 0.122161,0.35039 0,0.41592 -0.175318,0.0941 -0.360018,-0.18604 -0.497311,-0.33004 -0.16837,-0.17657 -0.1867,-0.4736 -0.375258,-0.62844 -0.159504,-0.13098 -0.388091,-0.14067 -0.583221,-0.20796 -0.373936,-0.12898 -0.7493,-0.25377 -1.125749,-0.37526 -0.664104,-0.21433 -1.322705,-0.44932 -1.998319,-0.62392 -0.397748,-0.10278 -0.799809,-0.19509 -1.207108,-0.24865 -0.716915,-0.0943 -1.4428,-0.10549 -2.165589,-0.12659 -0.486568,-0.0142 -0.973534,0 -1.460314,0 -0.500327,0 -1.017297,-0.12793 -1.500982,0 -0.353642,0.0935 -0.696065,0.2831 -0.953955,0.54252 -0.280167,0.28184 -0.434075,0.67149 -0.583221,1.03984 -0.12401,0.30628 -0.21949,0.62974 -0.25318,0.95848 -0.02846,0.27776 -0.121359,0.61233 0.04521,0.8364 0.219837,0.29573 0.684081,0.27924 1.039839,0.37526 0.517684,0.13971 1.053254,0.20251 1.582367,0.28935 0.568061,0.0932 1.137444,0.17968 1.708971,0.24866 0.719957,0.0869 1.442958,0.14714 2.165588,0.20797 0.582665,0.049 1.16496,0.11788 1.749636,0.12659 0.639472,0.01 1.282065,-0.004 1.916933,-0.0814 0.421296,-0.0514 0.863891,-0.0723 1.247828,-0.25318 0.257823,-0.1215 0.411004,-0.40786 0.664581,-0.538 0.141808,-0.0728 0.301942,-0.13443 0.461168,-0.12659 0.117679,0.006 0.263279,0.0295 0.330042,0.12659 0.05464,0.0795 -0.08688,0.24745 0,0.28934 0.161327,0.0778 0.252253,-0.27299 0.420449,-0.33456 0.430398,-0.15754 0.916384,-0.0237 1.374404,-0.0407 0.304509,-0.0113 0.855478,-0.33989 0.913263,-0.0407 0.111471,0.577 -1.117336,0.36687 -1.663753,0.58322 -0.508767,0.20143 -1.004755,0.43402 -1.500981,0.66461 -0.462095,0.2147 -0.905775,0.46905 -1.374405,0.66913 -0.36793,0.15707 -0.739457,0.31197 -1.125749,0.41593 -1.020604,0.27471 -2.098464,0.28707 -3.123936,0.54252 -0.169254,0.0422 -0.323188,0.1529 -0.497337,0.16276 -0.410157,0.0232 -0.797877,-0.21286 -1.207108,-0.24866 -0.471594,-0.0413 -0.946944,0.0145 -1.419622,0.0407 -0.514827,0.0285 -1.027589,0.0869 -1.541675,0.12659 -0.583009,0.045 -1.228222,-0.13804 -1.749663,0.12659 -0.209753,0.10645 -0.3919,0.31187 -0.456618,0.53801 -0.05407,0.18891 0.208132,0.42936 0.0859,0.58322 -0.641456,0.80748 -2.055204,0.17345 -3.083454,0.25318 -0.7638,0.0592 -1.528975,0.1007 -2.292192,0.16728 -1.085003,0.0947 -2.161699,0.34864 -3.250671,0.33004 -0.714745,-0.0122 -1.414621,-0.37005 -2.124895,-0.28935 -0.30898,0.0351 -0.566102,0.27734 -0.872569,0.33004 -1.902989,0.32719 -3.8608,-0.0912 -5.791465,-0.12207 -1.24923,-0.02 -2.505842,0.094 -3.748087,-0.0407 -0.338217,-0.0367 -0.717233,-0.0176 -0.999146,-0.20796 -0.373751,-0.25242 -0.428678,-0.80979 -0.750491,-1.12575 -0.422698,-0.415 -0.970968,-0.68506 -1.496483,-0.95848 -0.45384,-0.23612 -0.924349,-0.45506 -1.419622,-0.58323 -0.351076,-0.0908 -0.718794,-0.15203 -1.080532,-0.12659 -0.544036,0.0383 -1.081088,0.20115 -1.582367,0.41593 -0.390578,0.16736 -0.746628,0.41214 -1.085057,0.66913 -0.390683,0.29665 -0.701198,0.6881 -1.080531,0.99915 -0.05758,0.0472 -0.109535,0.10968 -0.180843,0.13111 -0.431932,0.1298 -0.901806,-0.0281 -1.351809,-0.0588 -1.4964,-0.10192 -2.989788,-0.24918 -4.48045,-0.41592 -1.199303,-0.13417 -2.390325,-0.60354 -3.589602,-0.47019 -0.395658,0.044 -0.871802,0.10113 -1.121225,0.41143 -0.273473,0.3402 -0.355706,0.89963 -0.176324,1.29754 0.262142,0.58148 1.022298,0.77449 1.591416,1.06246 1.639385,0.82952 3.502025,1.13498 5.181071,1.88077 0.690668,0.30675 1.332071,0.71432 2.002843,1.06246 1.270582,0.65944 2.563997,1.2746 3.829314,1.94405 0.971788,0.51416 1.917224,1.07717 2.888986,1.59142 1.226555,0.64907 2.463191,1.27968 3.711839,1.88528 0.797772,0.38696 1.596205,0.77468 2.414244,1.1167 0.308874,0.12914 0.60915,0.30412 0.940382,0.35264 1.714262,0.25109 3.459162,-0.20784 5.185569,-0.35264 1.376389,-0.11544 2.764896,-0.16151 4.123266,-0.41142 1.480238,-0.27231 2.893219,-0.83487 4.358217,-1.17999 2.709598,-0.63839 5.442744,-1.18219 8.187531,-1.64566 2.287323,-0.38621 4.630209,-0.44159 6.894513,-0.9449 1.74535,-0.38794 3.361002,-1.28434 5.122333,-1.59142 1.316646,-0.22955 2.682082,0.01 4.005792,-0.17632 1.499288,-0.21057 2.947988,-0.69212 4.417219,-1.05794 0.531677,-0.13238 1.063937,-0.26318 1.591417,-0.41142 1.40255,-0.39415 2.80829,-0.78492 4.182,-1.27043 0.52269,-0.18474 0.99605,-0.5258 1.54168,-0.62391 0.46445,-0.0835 0.95186,0.13062 1.41509,0.0407 0.47633,-0.0925 0.85387,-0.51115 1.33372,-0.58322 0.4845,-0.0728 0.9806,0.26686 1.46031,0.16728 0.29813,-0.0619 0.49572,-0.38299 0.79119,-0.45662 0.37748,-0.0941 0.77882,0.0744 1.16641,0.0407 0.80563,-0.0701 1.60216,-0.25913 2.37358,-0.50184 0.47471,-0.14937 0.92234,-0.37504 1.3744,-0.58322 0.3379,-0.15562 0.63524,-0.42005 0.99915,-0.49731 0.61235,-0.13003 1.39602,-0.3202 1.87624,0.0814 0.14221,0.11891 -0.0605,0.51062 0.12205,0.54253 0.17957,0.0314 0.12938,-0.38261 0.2939,-0.46114 0.89511,-0.42731 2.00115,0.0688 2.95672,0.33456 0.19166,0.0533 0.34816,0.20624 0.54253,0.24866 0.5698,0.12436 1.16644,0 1.74966,0 0.69323,0 1.38673,-0.0198 2.07968,0 0.50096,0.0143 1.00327,0.0275 1.50101,0.0859 0.39224,0.046 0.77795,0.13667 1.16641,0.20797 2.72415,0.50004 5.39538,1.52252 8.16504,1.54168 0.3243,0.002 0.95224,0.15698 0.95845,-0.16728 0.0574,-2.98186 -5.81792,-1.32149 -8.74818,-1.87624 -1.42406,-0.26959 -2.84982,-0.54713 -4.29048,-0.70527 -0.99475,-0.1092 -2.00165,-0.0687 -2.99747,-0.16729 -0.97708,-0.0968 -2.11947,0.15808 -2.91597,-0.41592 -0.12575,-0.0906 -0.25985,-0.26988 -0.20799,-0.41593 0.21421,-0.60317 1.17676,-0.50575 1.74967,-0.79118 0.46722,-0.23279 0.93334,-0.47133 1.3744,-0.75049 0.25979,-0.16445 0.6132,-0.26522 0.74597,-0.54253 0.11991,-0.2504 -0.10795,-0.56253 -0.0407,-0.83188 0.0983,-0.39341 0.41195,-0.69866 0.62391,-1.04436 0.20563,-0.33544 0.4473,-0.64987 0.62841,-0.99915 0.13153,-0.25368 0.25887,-0.51443 0.33004,-0.79118 0.0347,-0.13507 0.10745,-0.29115 0.0452,-0.41593 -0.0368,-0.0738 -0.13086,-0.11504 -0.21248,-0.12659 -0.38259,-0.0541 -0.7959,0.0855 -1.12125,0.29388 -0.25787,0.16516 -0.28173,0.656 -0.5832,0.70979 -0.19084,0.0341 -0.31996,-0.22684 -0.50186,-0.29387 -0.14505,-0.0535 -0.30901,-0.12737 -0.45662,-0.0814 -0.20653,0.0644 -0.30813,0.30369 -0.46114,0.45662 -0.16656,0.16649 -0.44884,0.27138 -0.49731,0.50183 -0.0243,0.11531 0.18711,0.22895 0.12657,0.33004 -0.17324,0.2893 -0.66656,0.11833 -1.00367,0.12659 -0.37473,0.009 -0.75054,-0.0303 -1.12122,-0.0859 -0.1833,-0.0275 -0.35764,-0.10889 -0.54253,-0.12207 -0.51419,-0.0367 -1.0342,0.0315 -1.5417,0.12207 -0.45463,0.0812 -0.87847,0.2975 -1.33368,0.37526 -0.23223,0.0397 -0.47771,-0.0156 -0.7053,0.0452 -0.24027,0.0642 -0.44741,0.21735 -0.66911,0.33004 -0.32149,0.16342 -0.61344,0.39693 -0.95848,0.50184 -0.12036,0.0366 -0.28159,0.12472 -0.37523,0.0407 -0.27929,-0.25063 -0.29038,-0.88805 0,-1.12575 0.16534,-0.13536 0.41542,0.10939 0.62841,0.12659 0.35925,0.029 0.73335,0.0561 1.08053,-0.0407 0.30539,-0.0851 0.59172,-0.25415 0.83188,-0.46114 0.27763,-0.2393 0.48548,-0.55534 0.6691,-0.87257 0.14314,-0.24731 0.27395,-0.51099 0.33007,-0.79118 0.0464,-0.232 0.0764,-0.48591 0,-0.7098 -0.0733,-0.21452 -0.28487,-0.35306 -0.41595,-0.53801 -0.35412,-0.49961 -0.68469,-1.01621 -0.99917,-1.54167 -0.39934,-0.66734 -0.72848,-1.37494 -1.12572,-2.04354 -0.21014,-0.35364 -0.33462,-0.79423 -0.66461,-1.03984 -0.2426,-0.18057 -0.61965,-0.0828 -0.87257,-0.24866 -0.0913,-0.0599 -0.184,-0.14663 -0.20797,-0.25318 -0.0628,-0.27884 0.1616,-0.54983 0.20797,-0.83187 0.0272,-0.16561 -0.004,-0.34018 0.0407,-0.50184 0.0913,-0.3275 0.35399,-0.58814 0.45567,-0.9126 0.0884,-0.28212 0.0845,-0.37446 0.0651,-0.66947 -0.0109,-0.16567 0.0558,-0.58301 -0.0731,-0.6875 -0.0704,-0.057 -0.20019,-0.0743 -0.27128,-0.0181 -0.21454,0.16966 -0.0571,0.54727 -0.13562,0.80928 -0.0984,0.32832 -0.0742,0.96631 -0.41593,0.94039 -0.20085,-0.0152 -0.13916,-0.3827 -0.15823,-0.58323 -0.0303,-0.31895 0.0511,-0.63878 0.0723,-0.95848 0.0175,-0.26358 0.12788,-0.5403 0.0452,-0.79118 -0.031,-0.0941 -0.0937,-0.20532 -0.19003,-0.2285 -0.10992,-0.0265 -0.14786,0.1834 -0.20767,0.27935 -0.1413,0.22666 0.0635,0.53409 0.041,0.80023 -0.0216,0.25542 -0.0337,0.50959 -0.2717,0.60471 -0.13818,0.0552 -0.18962,-0.18742 -0.22495,-0.33197 -0.10757,-0.44022 0.14048,-0.91694 -0.0237,-1.377 -0.0437,-0.12246 -0.14167,-0.29078 -0.27125,-0.2803 -0.12626,0.0102 -0.21713,0.18528 -0.21701,0.31194 0,0.27832 0.03,0.59455 0.03,0.84447 0,0.24992 0.0255,0.58674 -0.16566,0.62487 -0.15201,0.0303 -0.14864,-0.27273 -0.20795,-0.41593 -0.0839,-0.20253 -0.12927,-0.41931 -0.20799,-0.62391 -0.037,-0.096 -0.0398,-0.22342 -0.12385,-0.28276 -0.0773,-0.0545 -0.21764,-0.0885 -0.28303,-0.0202 -0.19091,0.19945 0.0818,0.54705 0.0949,0.82283 0.0107,0.22584 -0.0163,0.45207 -0.0136,0.67815 0.003,0.23983 0.012,0.4798 0.0316,0.71885 0.0103,0.12556 0.094,0.25908 0.0452,0.37526 -0.0832,0.19817 -0.31909,0.49027 -0.51088,0.39333 -0.25427,-0.1285 0.0429,-0.57068 0.0181,-0.85448 -0.0134,-0.15457 0.0383,-0.37004 -0.0904,-0.45661 -0.11846,-0.0797 -0.32354,-0.0234 -0.42045,0.0814 -0.24508,0.26503 0.23206,1.0061 -0.12208,1.076 -0.16873,0.0333 -0.19366,-0.28913 -0.24865,-0.45212 -0.12083,-0.35803 -0.27638,-0.75943 -0.16729,-1.12122 0.0598,-0.19819 0.31753,-0.27903 0.41593,-0.46114 0.12964,-0.2399 0.18339,-0.51962 0.20798,-0.79119 0.0338,-0.3733 -0.0193,-0.75234 -0.0859,-1.121222 -0.0619,-0.342636 -0.14785,-0.685536 -0.28935,-1.003671 -0.0858,-0.192958 -0.28209,-0.333454 -0.33456,-0.538004 -0.0622,-0.242678 0.11591,-0.511519 0.0407,-0.75049 -0.0264,-0.08397 -0.10126,-0.144989 -0.16276,-0.207968 -0.21395,-0.219094 -0.4313,-0.45593 -0.70982,-0.583221 -0.15436,-0.07054 -0.33936,-0.03688 -0.50184,-0.0859 -0.26033,-0.07854 -0.47704,-0.29001 -0.74599,-0.330041 z m -57.422524,22.096148 1.374405,0.28935 0.831876,0.62844 1.12575,0.66461 -0.289349,0.0814 -5.9182,-0.12207 0.04521,-0.29387 1.288495,-0.79119 z" />
+  </g>
+</svg>
diff --git a/book/src/img/parent-child.svg b/book/src/img/parent-child.svg
new file mode 100644
index 0000000..7b274c9
--- /dev/null
+++ b/book/src/img/parent-child.svg
@@ -0,0 +1 @@
+<svg id="graph-div" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="154" style="max-width: 179.03125px;" viewBox="0 0 179.03125 154"><style>#graph-div {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}#graph-div .error-icon{fill:#a44141;}#graph-div .error-text{fill:#ddd;stroke:#ddd;}#graph-div .edge-thickness-normal{stroke-width:2px;}#graph-div .edge-thickness-thick{stroke-width:3.5px;}#graph-div .edge-pattern-solid{stroke-dasharray:0;}#graph-div .edge-pattern-dashed{stroke-dasharray:3;}#graph-div .edge-pattern-dotted{stroke-dasharray:2;}#graph-div .marker{fill:lightgrey;stroke:lightgrey;}#graph-div .marker.cross{stroke:lightgrey;}#graph-div svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#graph-div .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#graph-div .cluster-label text{fill:#F9FFFE;}#graph-div .cluster-label span{color:#F9FFFE;}#graph-div .label text,#graph-div span{fill:#ccc;color:#ccc;}#graph-div .node rect,#graph-div .node circle,#graph-div .node ellipse,#graph-div .node polygon,#graph-div .node path{fill:#1f2020;stroke:#81B1DB;stroke-width:1px;}#graph-div .node .label{text-align:center;}#graph-div .node.clickable{cursor:pointer;}#graph-div .arrowheadPath{fill:lightgrey;}#graph-div .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#graph-div .flowchart-link{stroke:lightgrey;fill:none;}#graph-div .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#graph-div .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#graph-div .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#graph-div .cluster text{fill:#F9FFFE;}#graph-div .cluster span{color:#F9FFFE;}#graph-div div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#graph-div :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath LS-A LE-B" style="opacity: 1;" id="L-A-B"><path class="path" d="M64.58643617021276,52L59.864998891843975,56.166666666666664C55.14356161347518,60.333333333333336,45.70068705673759,68.66666666666667,40.979249778368796,77C36.2578125,85.33333333333333,36.2578125,93.66666666666667,36.2578125,97.83333333333333L36.2578125,102" marker-end="url(#arrowhead552)" style="fill:none"></path><defs><marker id="arrowhead552" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath LS-A LE-C" style="opacity: 1;" id="L-A-C"><path class="path" d="M114.44481382978724,52L119.16625110815603,56.166666666666664C123.88768838652481,60.333333333333336,133.3305629432624,68.66666666666667,138.0520002216312,77C142.7734375,85.33333333333333,142.7734375,93.66666666666667,142.7734375,97.83333333333333L142.7734375,102" marker-end="url(#arrowhead553)" style="fill:none"></path><defs><marker id="arrowhead553" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><rect rx="0" ry="0" width="0" height="0"></rect><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-A-B" class="edgeLabel L-LS-A' L-LE-B"></span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><rect rx="0" ry="0" width="0" height="0"></rect><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-A-C" class="edgeLabel L-LS-A' L-LE-C"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node default" style="opacity: 1;" id="flowchart-A-606" transform="translate(89.515625,30)"><rect rx="0" ry="0" x="-33.3046875" y="-22" width="66.609375" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-23.3046875,-12)"><foreignObject width="46.609375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Parent</div></foreignObject></g></g></g><g class="node default" style="opacity: 1;" id="flowchart-B-607" transform="translate(36.2578125,124)"><rect rx="5" ry="5" x="-28.2578125" y="-22" width="56.515625" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-18.2578125,-12)"><foreignObject width="36.515625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Child</div></foreignObject></g></g></g><g class="node default" style="opacity: 1;" id="flowchart-C-609" transform="translate(142.7734375,124)"><rect rx="5" ry="5" x="-28.2578125" y="-22" width="56.515625" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-18.2578125,-12)"><foreignObject width="36.515625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Child</div></foreignObject></g></g></g></g></g></g></svg>
\ No newline at end of file
diff --git a/book/src/img/prop-flow.svg b/book/src/img/prop-flow.svg
new file mode 100644
index 0000000..c779480
--- /dev/null
+++ b/book/src/img/prop-flow.svg
@@ -0,0 +1 @@
+<svg id="graph-div" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="154" style="max-width: 711.5625px;" viewBox="0 0 711.5625 154"><style>#graph-div {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}#graph-div .error-icon{fill:#a44141;}#graph-div .error-text{fill:#ddd;stroke:#ddd;}#graph-div .edge-thickness-normal{stroke-width:2px;}#graph-div .edge-thickness-thick{stroke-width:3.5px;}#graph-div .edge-pattern-solid{stroke-dasharray:0;}#graph-div .edge-pattern-dashed{stroke-dasharray:3;}#graph-div .edge-pattern-dotted{stroke-dasharray:2;}#graph-div .marker{fill:lightgrey;stroke:lightgrey;}#graph-div .marker.cross{stroke:lightgrey;}#graph-div svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#graph-div .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#graph-div .cluster-label text{fill:#F9FFFE;}#graph-div .cluster-label span{color:#F9FFFE;}#graph-div .label text,#graph-div span{fill:#ccc;color:#ccc;}#graph-div .node rect,#graph-div .node circle,#graph-div .node ellipse,#graph-div .node polygon,#graph-div .node path{fill:#1f2020;stroke:#81B1DB;stroke-width:1px;}#graph-div .node .label{text-align:center;}#graph-div .node.clickable{cursor:pointer;}#graph-div .arrowheadPath{fill:lightgrey;}#graph-div .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#graph-div .flowchart-link{stroke:lightgrey;fill:none;}#graph-div .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#graph-div .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#graph-div .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#graph-div .cluster text{fill:#F9FFFE;}#graph-div .cluster span{color:#F9FFFE;}#graph-div div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#graph-div :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath LS-PM LE-A" style="opacity: 1;" id="L-PM-A"><path class="path" d="M137.59375,77L151.51302083333334,77C165.43229166666666,77,193.27083333333334,77,221.109375,77C248.94791666666666,77,276.7864583333333,77,290.7057291666667,77L304.625,77" marker-end="url(#arrowhead3011)" style="fill:none"></path><defs><marker id="arrowhead3011" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath LS-A LE-B" style="opacity: 1;" id="L-A-B"><path class="path" d="M404.984375,60.263236680157455L420.1067708333333,55.21936390013121C435.2291666666667,50.17549112010497,465.4739583333333,40.08774556005249,495.71875,35.04387278002624C525.9635416666666,30,556.2083333333334,30,571.3307291666666,30L586.453125,30" marker-end="url(#arrowhead3012)" style="fill:none"></path><defs><marker id="arrowhead3012" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath LS-A LE-C" style="opacity: 1;" id="L-A-C"><path class="path" d="M404.984375,93.73676331984254L420.1067708333333,98.78063609986879C435.2291666666667,103.82450887989502,465.4739583333333,113.91225443994752,496.59375,118.95612721997377C527.7135416666666,124,559.7083333333334,124,575.7057291666666,124L591.703125,124" marker-end="url(#arrowhead3013)" style="fill:none"></path><defs><marker id="arrowhead3013" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" style="opacity: 1;" transform="translate(221.109375,77)"><g transform="translate(-58.515625,-12)" class="label"><rect rx="0" ry="0" width="117.03125" height="24"></rect><foreignObject width="117.03125" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-PM-A" class="edgeLabel L-LS-PM' L-LE-A">Pass Player Data</span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform="translate(495.71875,30)"><g transform="translate(-65.734375,-12)" class="label"><rect rx="0" ry="0" width="131.46875" height="24"></rect><foreignObject width="131.46875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-A-B" class="edgeLabel L-LS-A' L-LE-B">Pass Player Health</span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform="translate(495.71875,124)"><g transform="translate(-60.484375,-12)" class="label"><rect rx="0" ry="0" width="120.96875" height="24"></rect><foreignObject width="120.96875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-A-C" class="edgeLabel L-LS-A' L-LE-C">Pass Player Mana</span></div></foreignObject></g></g></g><g class="nodes"><g class="node default" style="opacity: 1;" id="flowchart-PM-3064" transform="translate(72.796875,77)"><rect rx="0" ry="0" x="-64.796875" y="-22" width="129.59375" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-54.796875,-12)"><foreignObject width="109.59375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Player Manager</div></foreignObject></g></g></g><g class="node default" style="opacity: 1;" id="flowchart-A-3065" transform="translate(354.8046875,77)"><rect rx="0" ry="0" x="-50.1796875" y="-22" width="100.359375" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40.1796875,-12)"><foreignObject width="80.359375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Player HUD</div></foreignObject></g></g></g><g class="node default" style="opacity: 1;" id="flowchart-B-3067" transform="translate(645.0078125,30)"><rect rx="5" ry="5" x="-58.5546875" y="-22" width="117.109375" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-48.5546875,-12)"><foreignObject width="97.109375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Player Health</div></foreignObject></g></g></g><g class="node default" style="opacity: 1;" id="flowchart-C-3069" transform="translate(645.0078125,124)"><rect rx="5" ry="5" x="-53.3046875" y="-22" width="106.609375" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-43.3046875,-12)"><foreignObject width="86.609375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Player Mana</div></foreignObject></g></g></g></g></g></g></svg>
\ No newline at end of file
diff --git a/book/src/introduction.md b/book/src/introduction.md
index b6813a6..b73e0fc 100644
--- a/book/src/introduction.md
+++ b/book/src/introduction.md
@@ -1,3 +1,8 @@
+<p align="center">
+    <img src="img/kayak.svg" alt="Kayak UI" width="600" />
+</p>
+<br/>
+
 # Introduction
 
 Kayak UI is a declarative UI that can be used to make user interfaces in Rust primarily targeting games. It's free and open-source!
diff --git a/examples/bevy_scene.rs b/examples/bevy_scene.rs
index dc9f966..e57e0db 100644
--- a/examples/bevy_scene.rs
+++ b/examples/bevy_scene.rs
@@ -62,7 +62,7 @@ fn set_active_tile_target(
     // }
     // ```
 
-    let world_pos = cursor_to_world(&windows, &camera_transform.single());
+    let world_pos = cursor_to_world(&windows, camera_transform.single());
     let tile_pos = world_to_tile(world_pos);
     let mut tile = tile.single_mut();
     tile.target = tile_pos;
@@ -87,7 +87,7 @@ fn move_ghost_tile(
 ) {
     for _ in cursor_moved.iter() {
         if !event_context.contains_cursor() {
-            let world_pos = cursor_to_world(&windows, &camera_transform.single());
+            let world_pos = cursor_to_world(&windows, camera_transform.single());
             let tile_pos = world_to_tile(world_pos);
             let mut ghost = tile.single_mut();
             ghost.translation.x = tile_pos.x;
diff --git a/examples/clipping.rs b/examples/clipping.rs
index 47ab6c1..b9c32fa 100644
--- a/examples/clipping.rs
+++ b/examples/clipping.rs
@@ -39,7 +39,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque.
         <KayakAppBundle>
             <NinePatchBundle
                 nine_patch={NinePatch {
-                    handle: image.clone(),
+                    handle: image,
                     border: Edge::all(30.0),
                 }}
                 styles={nine_patch_styles}
diff --git a/examples/context.rs b/examples/context.rs
index bc128df..8147520 100644
--- a/examples/context.rs
+++ b/examples/context.rs
@@ -162,7 +162,7 @@ fn update_theme_selector(
     mut commands: Commands,
     query: Query<&ThemeSelector>,
 ) -> bool {
-    if let Ok(_) = query.get(entity) {
+    if query.get(entity).is_ok() {
         let button_container_style = KStyle {
             layout_type: StyleProp::Value(LayoutType::Row),
             width: StyleProp::Value(Units::Stretch(1.0)),
@@ -188,7 +188,7 @@ fn update_theme_selector(
     true
 }
 
-#[derive(Component, Debug, Default, Clone, PartialEq)]
+#[derive(Component, Debug, Default, Clone, PartialEq, Eq)]
 pub struct ThemeDemo {
     is_root: bool,
     context_entity: Option<Entity>,
@@ -227,11 +227,9 @@ fn update_theme_demo(
                     format!("Select A Different Theme (Current: {})", theme.name)
                 };
 
-                if theme_demo.is_root {
-                    if theme_demo.context_entity.is_none() {
-                        let theme_entity = commands.spawn(Theme::vector()).id();
-                        theme_demo.context_entity = Some(theme_entity);
-                    }
+                if theme_demo.is_root && theme_demo.context_entity.is_none() {
+                    let theme_entity = commands.spawn(Theme::vector()).id();
+                    theme_demo.context_entity = Some(theme_entity);
                 }
 
                 let context_entity = if let Some(entity) = theme_demo.context_entity {
@@ -283,13 +281,13 @@ fn update_theme_demo(
                                 text={TextProps {
                                     content: "Lorem ipsum dolor...".into(),
                                     size: 12.0,
-                                    user_styles: text_styles.clone(),
+                                    user_styles: text_styles,
                                     ..Default::default()
                                 }}
                             />
                             <KButtonBundle
                                 button={KButton { text: "BUTTON".into(), ..Default::default() }}
-                                styles={btn_style.clone()}
+                                styles={btn_style}
                             />
                             {
                                 if theme_demo.is_root {
diff --git a/examples/demo.rs b/examples/demo.rs
index 0f49c39..2d63f72 100644
--- a/examples/demo.rs
+++ b/examples/demo.rs
@@ -1,7 +1,7 @@
 use bevy::prelude::*;
 use kayak_ui::prelude::{widgets::*, *};
 
-#[derive(Debug, Component, Default, Clone, PartialEq)]
+#[derive(Debug, Component, Default, Clone, PartialEq, Eq)]
 pub struct MyWidget {
     pub foo: u32,
 }
diff --git a/examples/image.rs b/examples/image.rs
index c2dabf9..990607a 100644
--- a/examples/image.rs
+++ b/examples/image.rs
@@ -17,7 +17,7 @@ fn startup(
     rsx! {
         <KayakAppBundle>
             <KImageBundle
-                image={KImage(image.clone())}
+                image={KImage(image)}
                 style={KStyle {
                     position_type: StyleProp::Value(KPositionType::SelfDirected),
                     left: StyleProp::Value(Units::Pixels(10.0)),
diff --git a/examples/nine_patch.rs b/examples/nine_patch.rs
index 5dd452d..2ddf562 100644
--- a/examples/nine_patch.rs
+++ b/examples/nine_patch.rs
@@ -40,7 +40,7 @@ fn startup(
         <KayakAppBundle>
             <NinePatchBundle
                 nine_patch={NinePatch {
-                    handle: image.clone(),
+                    handle: image,
                     border: Edge::all(15.0),
                 }}
                 styles={KStyle {
diff --git a/examples/simple_state.rs b/examples/simple_state.rs
index e55f5b2..8f5be82 100644
--- a/examples/simple_state.rs
+++ b/examples/simple_state.rs
@@ -42,7 +42,7 @@ fn current_count_render(
                 <TextWidgetBundle
                     text={
                         TextProps {
-                            content: format!("Current Count: {}", current_count.foo).into(),
+                            content: format!("Current Count: {}", current_count.foo),
                             size: 16.0,
                             line_height: Some(40.0),
                             ..Default::default()
diff --git a/examples/tabs/tab.rs b/examples/tabs/tab.rs
index 1260842..f6f2827 100644
--- a/examples/tabs/tab.rs
+++ b/examples/tabs/tab.rs
@@ -6,7 +6,7 @@ use kayak_ui::prelude::{
 
 use crate::tab_context::TabContext;
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct Tab {
     pub index: usize,
 }
diff --git a/examples/tabs/tab_button.rs b/examples/tabs/tab_button.rs
index 6099a8f..d9ca5dc 100644
--- a/examples/tabs/tab_button.rs
+++ b/examples/tabs/tab_button.rs
@@ -9,7 +9,7 @@ use kayak_ui::{
 
 use crate::tab_context::TabContext;
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct TabButton {
     pub index: usize,
     pub title: String,
@@ -83,7 +83,6 @@ pub fn tab_button_render(
                             height: StyleProp::Value(Units::Pixels(25.0)),
                             ..Default::default()
                         },
-                        ..Default::default()
                     }}
                     on_event={on_event}
                 />
diff --git a/examples/tabs/tab_context.rs b/examples/tabs/tab_context.rs
index 2c6e5f2..47af5bc 100644
--- a/examples/tabs/tab_context.rs
+++ b/examples/tabs/tab_context.rs
@@ -1,12 +1,12 @@
 use bevy::prelude::{Bundle, Commands, Component, Entity, In, Query};
 use kayak_ui::prelude::*;
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct TabContext {
     pub current_index: usize,
 }
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct TabContextProvider {
     pub initial_index: usize,
 }
diff --git a/examples/text.rs b/examples/text.rs
index 141d542..3d6ae7e 100644
--- a/examples/text.rs
+++ b/examples/text.rs
@@ -1,7 +1,7 @@
 use bevy::prelude::*;
 use kayak_ui::prelude::{widgets::*, KStyle, *};
 
-#[derive(Component, Default, Clone, PartialEq)]
+#[derive(Component, Default, Clone, PartialEq, Eq)]
 pub struct MyWidgetProps {
     pub foo: u32,
 }
@@ -17,7 +17,7 @@ fn my_widget_1_render(
         // Note: We will see two updates because of the mutable change to styles.
         // Which means when foo changes MyWidget will render twice!
         style.render_command = StyleProp::Value(RenderCommand::Text {
-            content: format!("My number is: {}", my_widget.foo).to_string(),
+            content: format!("My number is: {}", my_widget.foo),
             alignment: Alignment::Start,
             word_wrap: false,
         });
diff --git a/examples/texture_atlas.rs b/examples/texture_atlas.rs
index 369ad47..8d78df6 100644
--- a/examples/texture_atlas.rs
+++ b/examples/texture_atlas.rs
@@ -60,11 +60,11 @@ fn startup(
             />
             <TextureAtlasBundle
                 atlas={TextureAtlasProps {
-                    handle: image_handle.clone(),
+                    handle: image_handle,
                     position: flower_position,
                     tile_size: flower_size,
                 }}
-                styles={atlas_styles.clone()}
+                styles={atlas_styles}
             />
         </KayakAppBundle>
     }
diff --git a/examples/todo/input.rs b/examples/todo/input.rs
index 6e6b156..1212065 100644
--- a/examples/todo/input.rs
+++ b/examples/todo/input.rs
@@ -3,7 +3,7 @@ use kayak_ui::prelude::{widgets::*, *};
 
 use crate::TodoList;
 
-#[derive(Component, Default, Clone, PartialEq)]
+#[derive(Component, Default, Clone, PartialEq, Eq)]
 pub struct TodoInputProps;
 
 impl Widget for TodoInputProps {}
diff --git a/examples/todo/items.rs b/examples/todo/items.rs
index 2956999..99c802c 100644
--- a/examples/todo/items.rs
+++ b/examples/todo/items.rs
@@ -3,7 +3,7 @@ use kayak_ui::prelude::{widgets::*, *};
 
 use crate::TodoList;
 
-#[derive(Component, Default, Clone, PartialEq)]
+#[derive(Component, Default, Clone, PartialEq, Eq)]
 pub struct TodoItemsProps;
 
 impl Widget for TodoItemsProps {}
diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs
index 3da0b59..36687d9 100644
--- a/examples/todo/todo.rs
+++ b/examples/todo/todo.rs
@@ -15,6 +15,12 @@ pub struct TodoList {
     pub items: Vec<String>,
 }
 
+impl Default for TodoList {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl TodoList {
     pub fn new() -> Self {
         Self {
diff --git a/examples/vec.rs b/examples/vec.rs
index 732cb90..9e412a8 100644
--- a/examples/vec.rs
+++ b/examples/vec.rs
@@ -1,7 +1,7 @@
 use bevy::prelude::*;
 use kayak_ui::prelude::{widgets::*, KStyle, *};
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct MyWidgetProps {}
 
 fn my_widget_1_update(
@@ -9,7 +9,7 @@ fn my_widget_1_update(
     mut commands: Commands,
     query: Query<Entity, Or<(With<Mounted>, Changed<MyWidgetProps>)>>,
 ) -> bool {
-    if let Ok(_) = query.get(entity) {
+    if query.get(entity).is_ok() {
         let parent_id = Some(entity);
         let data = vec![
             "Text 1", "Text 2", "Text 3", "Text 4", "Text 5", "Text 6", "Text 7", "Text 8",
@@ -21,7 +21,7 @@ fn my_widget_1_update(
                     constructor! {
                         <TextWidgetBundle
                             text={TextProps {
-                                content: text.clone().into(),
+                                content: (*text).clone().into(),
                                 ..Default::default()
                             }}
                         />
diff --git a/kayak_font/src/atlas.rs b/kayak_font/src/atlas.rs
index e710863..917163e 100644
--- a/kayak_font/src/atlas.rs
+++ b/kayak_font/src/atlas.rs
@@ -1,12 +1,12 @@
 use nanoserde::DeJson;
 
-#[derive(DeJson, Debug, Copy, Clone, PartialEq)]
+#[derive(DeJson, Debug, Copy, Clone, PartialEq, Eq)]
 pub enum SDFType {
     #[nserde(rename = "msdf")]
     Msdf,
 }
 
-#[derive(DeJson, Debug, Copy, Clone, PartialEq)]
+#[derive(DeJson, Debug, Copy, Clone, PartialEq, Eq)]
 pub enum Origin {
     #[nserde(rename = "bottom")]
     Bottom,
diff --git a/kayak_font/src/bevy/renderer/font_texture_cache.rs b/kayak_font/src/bevy/renderer/font_texture_cache.rs
index 3213ccd..5bd2981 100644
--- a/kayak_font/src/bevy/renderer/font_texture_cache.rs
+++ b/kayak_font/src/bevy/renderer/font_texture_cache.rs
@@ -52,11 +52,9 @@ impl FontTextureCache {
         if !self.fonts.contains_key(&kayak_font_handle) {
             self.fonts.insert(kayak_font_handle.clone(), font);
             self.new_fonts.push(kayak_font_handle);
-        } else {
-            if let Some(old_font) = self.fonts.get_mut(&kayak_font_handle) {
-                *old_font = font;
-                self.updated_fonts.push(kayak_font_handle);
-            }
+        } else if let Some(old_font) = self.fonts.get_mut(&kayak_font_handle) {
+            *old_font = font;
+            self.updated_fonts.push(kayak_font_handle);
         }
     }
 
@@ -256,7 +254,7 @@ impl FontTextureCache {
                     resource: BindingResource::Sampler(&gpu_image.sampler),
                 },
             ],
-            layout: &pipeline.get_font_image_layout(),
+            layout: pipeline.get_font_image_layout(),
         });
 
         bind_groups.insert(font_handle.clone_weak(), binding);
diff --git a/kayak_font/src/font.rs b/kayak_font/src/font.rs
index b1143fc..38d4c02 100644
--- a/kayak_font/src/font.rs
+++ b/kayak_font/src/font.rs
@@ -63,10 +63,8 @@ impl KayakFont {
     }
 
     pub fn generate_char_ids(&mut self) {
-        let mut count = 0;
-        for glyph in self.sdf.glyphs.iter() {
-            self.char_ids.insert(glyph.unicode, count);
-            count += 1;
+        for (count, glyph) in self.sdf.glyphs.iter().enumerate() {
+            self.char_ids.insert(glyph.unicode, count as u32);
         }
     }
 
@@ -408,7 +406,7 @@ impl KayakFont {
         }
 
         // 9.
-        return (Some(best_break_index), Some(best_break_index));
+        (Some(best_break_index), Some(best_break_index))
     }
 
     /// Returns the pixel width of a space.
diff --git a/kayak_ui_macros/src/widget.rs b/kayak_ui_macros/src/widget.rs
index 01f0b33..65691a2 100644
--- a/kayak_ui_macros/src/widget.rs
+++ b/kayak_ui_macros/src/widget.rs
@@ -93,7 +93,7 @@ impl Widget {
             }
         } else {
             let attrs = &open_tag.attributes.for_custom_element(&children);
-            let name = syn::parse_str::<syn::Path>(&"fragment").unwrap();
+            let name = syn::parse_str::<syn::Path>("fragment").unwrap();
             let (entity_id, props, _) = Self::construct(&name, attrs, true, true, index);
             (
                 entity_id,
@@ -137,7 +137,7 @@ impl Widget {
             let value = attribute.value_tokens();
             let key_name = quote! { #key }.to_string();
             if key_name == "id" {
-                return Some(value);
+                Some(value)
             } else {
                 None
             }
@@ -145,7 +145,7 @@ impl Widget {
 
         let prop_ident = format_ident!("internal_rsx_props");
         let entity_id = if let Some(entity_name_id) = entity_name_id {
-            let entity_name_id = format_ident!("{}", entity_name_id.to_string().replace("\"", ""));
+            let entity_name_id = format_ident!("{}", entity_name_id.to_string().replace('"', ""));
             quote! { #entity_name_id }
         } else {
             quote! { widget_entity }
diff --git a/kayak_ui_macros/src/widget_attributes.rs b/kayak_ui_macros/src/widget_attributes.rs
index 85679d1..73a84d8 100644
--- a/kayak_ui_macros/src/widget_attributes.rs
+++ b/kayak_ui_macros/src/widget_attributes.rs
@@ -107,7 +107,7 @@ impl<'a, 'c> CustomWidgetAttributes<'a, 'c> {
 
     /// Determines whether `children` should be added to this widget or not
     pub fn should_add_children(&self) -> bool {
-        if self.children.nodes.len() == 0 {
+        if self.children.nodes.is_empty() {
             // No children
             false
         } else if self.children.nodes.len() == 1 {
@@ -115,7 +115,7 @@ impl<'a, 'c> CustomWidgetAttributes<'a, 'c> {
             match child {
                 Child::RawBlock((block, _)) => {
                     // Is child NOT an empty block? (`<Foo>{}</Foo>`)
-                    block.stmts.len() > 0
+                    !block.stmts.is_empty()
                 }
                 // Child is a widget
                 _ => true,
diff --git a/src/calculate_nodes.rs b/src/calculate_nodes.rs
index 4f03941..7d6a7a9 100644
--- a/src/calculate_nodes.rs
+++ b/src/calculate_nodes.rs
@@ -114,13 +114,12 @@ pub fn calculate_nodes(
                 dirty_entity,
                 &mut styles,
                 node_query
-                    .get(dirty_entity.0)
-                    .and_then(|(_, node)| Ok(node.raw_styles.clone().unwrap_or_default()))
+                    .get(dirty_entity.0).map(|(_, node)| node.raw_styles.clone().unwrap_or_default())
                     .unwrap_or_default(),
                 &all_styles_query,
             );
 
-            let children = tree.children.get(&dirty_entity).cloned().unwrap_or(vec![]);
+            let children = tree.children.get(&dirty_entity).cloned().unwrap_or_default();
 
             let width = styles.width.resolve().value_or(0.0, 0.0);
             let height = styles.height.resolve().value_or(0.0, 0.0);
@@ -147,8 +146,7 @@ pub fn calculate_nodes(
                 }
             }
             node.old_z = node_query
-                .get(dirty_entity.0)
-                .and_then(|old_node| Ok(old_node.1.z))
+                .get(dirty_entity.0).map(|old_node| old_node.1.z)
                 .unwrap_or(0.0);
             node.z = current_z;
             new_nodes.insert(dirty_entity.0, (node, needs_layout));
@@ -268,7 +266,7 @@ fn create_primitive(
                             }
 
                             // --- Calculate Text Layout --- //
-                            *text_layout = font.measure(&content, *properties);
+                            *text_layout = font.measure(content, *properties);
                             let measurement = text_layout.size();
 
                             log::trace!(
diff --git a/src/camera/camera.rs b/src/camera/camera.rs
index d7d990f..4f509ab 100644
--- a/src/camera/camera.rs
+++ b/src/camera/camera.rs
@@ -41,6 +41,12 @@ pub struct UICameraBundle {
     pub camera_ui: CameraUIKayak,
 }
 
+impl Default for UICameraBundle {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl UICameraBundle {
     pub const UI_CAMERA: &'static str = "KAYAK_UI_CAMERA";
     pub fn new() -> Self {
diff --git a/src/children.rs b/src/children.rs
index 10546b2..c2e2de6 100644
--- a/src/children.rs
+++ b/src/children.rs
@@ -3,7 +3,7 @@ use bevy::prelude::*;
 use crate::prelude::KayakWidgetContext;
 
 /// Defers widgets being added to the widget tree.
-#[derive(Component, Debug, Default, Clone, PartialEq)]
+#[derive(Component, Debug, Default, Clone, PartialEq, Eq)]
 pub struct KChildren {
     inner: Vec<Entity>,
 }
@@ -19,7 +19,7 @@ impl KChildren {
     }
 
     pub fn get(&self, index: usize) -> Option<Entity> {
-        self.inner.get(index).and_then(|e| Some(*e))
+        self.inner.get(index).copied()
     }
 
     pub fn remove(&mut self, index: usize) -> Option<Entity> {
@@ -38,6 +38,10 @@ impl KChildren {
         self.inner.len()
     }
 
+    pub fn is_empty(&self) -> bool {
+        self.inner.len() == 0
+    }
+
     pub fn despawn(&mut self, commands: &mut Commands) {
         for child in self.inner.drain(..) {
             commands.entity(child).despawn_recursive();
diff --git a/src/context.rs b/src/context.rs
index 0542553..f1bba5e 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -85,6 +85,12 @@ pub struct KayakRootContext {
     pub(crate) index: Arc<RwLock<HashMap<Entity, usize>>>,
 }
 
+impl Default for KayakRootContext {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl KayakRootContext {
     /// Creates a new widget context.
     pub fn new() -> Self {
@@ -166,10 +172,7 @@ impl KayakRootContext {
     /// so that the correct ordering is preserved for updates and rendering.
     pub fn add_widget(&mut self, parent: Option<Entity>, entity: Entity) {
         if let Ok(mut tree) = self.tree.write() {
-            tree.add(
-                WrappedIndex(entity),
-                parent.and_then(|p| Some(WrappedIndex(p))),
-            );
+            tree.add(WrappedIndex(entity), parent.map(WrappedIndex));
             if let Ok(mut cache) = self.layout_cache.try_write() {
                 cache.add(WrappedIndex(entity));
             }
@@ -224,10 +227,7 @@ impl KayakRootContext {
             );
             // We need to add it to the ordered tree
             if let Ok(mut tree) = self.order_tree.try_write() {
-                tree.add(
-                    WrappedIndex(entity.unwrap()),
-                    parent_id.and_then(|parent| Some(WrappedIndex(parent))),
-                )
+                tree.add(WrappedIndex(entity.unwrap()), parent_id.map(WrappedIndex))
             }
         }
         entity.unwrap()
@@ -248,7 +248,7 @@ impl KayakRootContext {
         if let Ok(mut hash_map) = self.index.try_write() {
             if hash_map.contains_key(&parent) {
                 let index = hash_map.get_mut(&parent).unwrap();
-                let current_index = index.clone();
+                let current_index = *index;
                 *index += 1;
                 return current_index;
             } else {
@@ -282,7 +282,7 @@ impl KayakRootContext {
 
         let render_primitives = if let Ok(mut layout_cache) = self.layout_cache.try_write() {
             recurse_node_tree_to_build_primitives(
-                &*node_tree,
+                &node_tree,
                 &mut layout_cache,
                 nodes,
                 widget_names,
@@ -320,19 +320,16 @@ fn recurse_node_tree_to_build_primitives(
     let mut render_primitives = Vec::new();
     if let Ok(node) = nodes.get(current_node.0) {
         let mut render_primitive = node.primitive.clone();
-        let mut new_z_index = if matches!(render_primitive, RenderPrimitive::Clip { .. }) {
-            main_z_index
-        } else {
-            main_z_index
-        };
+        let mut new_z_index = main_z_index;
+
         let _layout = if let Some(layout) = layout_cache.rect.get_mut(&current_node) {
-            // log::info!(
-            //     "z_index is {} and node.z is {} for: {}-{}",
-            //     new_z_index,
-            //     node.z,
-            //     widget_names.get(current_node.0).unwrap().0,
-            //     current_node.0.id(),
-            // );
+            log::trace!(
+                "z_index is {} and node.z is {} for: {}-{}",
+                new_z_index,
+                node.z,
+                widget_names.get(current_node.0).unwrap().0,
+                current_node.0.index(),
+            );
 
             new_z_index += if node.z <= 0.0 { 0.0 } else { node.z };
 
@@ -419,21 +416,21 @@ fn recurse_node_tree_to_build_primitives(
             "No render node: {}-{} > {}-{}",
             node_tree
                 .get_parent(current_node)
-                .and_then(|v| Some(v.0.index() as i32))
+                .map(|v| v.0.index() as i32)
                 .unwrap_or(-1),
             widget_names
                 .get(
                     node_tree
                         .get_parent(current_node)
-                        .and_then(|v| Some(v.0))
+                        .map(|v| v.0)
                         .unwrap_or(Entity::from_raw(0))
                 )
-                .and_then(|v| Ok(v.0.clone()))
-                .unwrap_or("None".into()),
+                .map(|v| v.0.clone())
+                .unwrap_or_else(|_| "None".into()),
             widget_names
                 .get(current_node.0)
-                .and_then(|v| Ok(v.0.clone()))
-                .unwrap_or("None".into()),
+                .map(|v| v.0.clone())
+                .unwrap_or_else(|_| "None".into()),
             current_node.0.index()
         );
     }
@@ -548,7 +545,7 @@ fn update_widgets(
                     order_tree.clone(),
                     index.clone(),
                 );
-                widget_context.copy_from_point(&tree, *entity);
+                widget_context.copy_from_point(tree, *entity);
                 let children_before = widget_context.get_children(entity.0);
                 let widget_name = widget_type.0.clone();
                 let (widget_context, should_update_children) = update_widget(
@@ -725,7 +722,7 @@ fn update_widget(
                     if let Ok(clone_systems) = clone_systems.try_read() {
                         for s in clone_systems.0.iter() {
                             s.0(world, *target_entity, entity.0);
-                            s.1(world, *target_entity, entity.0, &widget_state);
+                            s.1(world, *target_entity, entity.0, widget_state);
                             if let Some(styles) = world.entity(entity.0).get::<KStyle>().cloned() {
                                 if let Some(mut entity) = world.get_entity_mut(*target_entity) {
                                     entity.insert(styles);
@@ -957,7 +954,7 @@ fn calculate_ui(world: &mut World) {
 
 /// A simple component that stores the type name of a widget
 /// This is used by Kayak in order to find out which systems to run.
-#[derive(Component, Debug, Clone, PartialEq)]
+#[derive(Component, Debug, Clone, PartialEq, Eq)]
 pub struct WidgetName(pub String);
 
 impl From<String> for WidgetName {
@@ -968,6 +965,6 @@ impl From<String> for WidgetName {
 
 impl Into<String> for WidgetName {
     fn into(self) -> String {
-        self.0.into()
+        self.0
     }
 }
diff --git a/src/context_entities.rs b/src/context_entities.rs
index a2749a4..5037f39 100644
--- a/src/context_entities.rs
+++ b/src/context_entities.rs
@@ -35,6 +35,6 @@ impl ContextEntities {
             return None;
         }
         let inner = self.ce.get(&parent_id).unwrap();
-        inner.get(&T::default().type_id()).and_then(|e| Some(*e))
+        inner.get(&T::default().type_id()).map(|e| *e)
     }
 }
diff --git a/src/event.rs b/src/event.rs
index 773a89f..7d24367 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -7,7 +7,7 @@ use crate::{
 };
 
 /// An event type sent to widgets
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Clone)]
 pub struct Event {
     /// The node targeted by this event
     pub target: Entity,
@@ -21,8 +21,16 @@ pub struct Event {
     pub(crate) default_prevented: bool,
     /// OnChange systems to call afterwards
     pub(crate) on_change_systems: Vec<OnChange>,
+}
 
-    pub testing_z_index: f32,
+impl PartialEq for Event {
+    fn eq(&self, other: &Self) -> bool {
+        self.target == other.target
+            && self.current_target == other.current_target
+            && self.event_type == other.event_type
+            && self.should_propagate == other.should_propagate
+            && self.default_prevented == other.default_prevented
+    }
 }
 
 impl Default for Event {
@@ -34,7 +42,6 @@ impl Default for Event {
             should_propagate: true,
             default_prevented: false,
             on_change_systems: Vec::new(),
-            testing_z_index: 0.0,
         }
     }
 }
@@ -52,7 +59,6 @@ impl Event {
             should_propagate: event_type.propagates(),
             default_prevented: false,
             on_change_systems: Vec::new(),
-            testing_z_index: 0.0,
         }
     }
 
diff --git a/src/event_dispatcher.rs b/src/event_dispatcher.rs
index 3c80a66..970bc86 100644
--- a/src/event_dispatcher.rs
+++ b/src/event_dispatcher.rs
@@ -380,7 +380,7 @@ impl EventDispatcher {
             } else {
                 // No capturing widget -> process cursor events as normal
                 let mut stack: Vec<TreeNode> = vec![(root, 0)];
-                while stack.len() > 0 {
+                while !stack.is_empty() {
                     let (current, depth) = stack.pop().unwrap();
                     let mut enter_children = true;
 
@@ -421,8 +421,7 @@ impl EventDispatcher {
                             for child in children {
                                 let child_z = world
                                     .entity(child.0)
-                                    .get::<Node>()
-                                    .and_then(|node| Some(node.z))
+                                    .get::<Node>().map(|node| node.z)
                                     .unwrap_or(0.0);
                                 stack_children.push((child_z, (*child, depth + 1)));
                             }
@@ -737,7 +736,7 @@ impl EventDispatcher {
         layout: &Rect,
         event_type: EventType,
     ) {
-        let state = states.entry(event_type).or_insert(EventState::default());
+        let state = states.entry(event_type).or_default();
 
         let (node, depth) = tree_node;
         // Node is at or above best depth and is at or above best z-level
@@ -769,7 +768,7 @@ impl EventDispatcher {
         widget_id: &WrappedIndex,
         event_type: EventType,
     ) -> bool {
-        let entry = events.entry(*widget_id).or_insert(HashSet::default());
+        let entry = events.entry(*widget_id).or_default();
         entry.insert(event_type)
     }
 
diff --git a/src/focus_tree.rs b/src/focus_tree.rs
index f20fb6b..ab45348 100644
--- a/src/focus_tree.rs
+++ b/src/focus_tree.rs
@@ -5,7 +5,7 @@ use crate::{node::WrappedIndex, prelude::Tree};
 #[derive(Component, Default, Clone, Copy)]
 pub struct Focusable;
 
-#[derive(Debug, Default, PartialEq)]
+#[derive(Debug, Default, PartialEq, Eq)]
 pub struct FocusTree {
     tree: Tree,
     current_focus: Option<WrappedIndex>,
@@ -208,11 +208,7 @@ impl FocusTracker {
     pub fn get_focusability(&self, index: WrappedIndex) -> Option<bool> {
         if let Some(focusable) = self.widgets.get(&index) {
             Some(*focusable)
-        } else if let Some(focusable) = self.parents.get(&index) {
-            Some(*focusable)
-        } else {
-            None
-        }
+        } else { self.parents.get(&index).copied() }
     }
 }
 
diff --git a/src/layout_dispatcher.rs b/src/layout_dispatcher.rs
index a7320b6..29be716 100644
--- a/src/layout_dispatcher.rs
+++ b/src/layout_dispatcher.rs
@@ -20,7 +20,6 @@ impl LayoutEventDispatcher {
             let mut query = world.query_filtered::<Entity, With<OnLayout>>();
             query
                 .iter(world)
-                .map(|entity| entity)
                 .collect::<HashSet<_>>()
         };
 
diff --git a/src/node.rs b/src/node.rs
index 820e79d..d10ba9e 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -121,7 +121,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::LayoutType::default()),
             };
         }
-        return Some(morphorm::LayoutType::default());
+        Some(morphorm::LayoutType::default())
     }
 
     fn position_type(&self, store: &'_ Self::Data) -> Option<morphorm::PositionType> {
@@ -132,7 +132,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::PositionType::default()),
             };
         }
-        return Some(morphorm::PositionType::default());
+        Some(morphorm::PositionType::default())
     }
 
     fn width(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -143,7 +143,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Stretch(1.0)),
             };
         }
-        return Some(morphorm::Units::Stretch(1.0));
+        Some(morphorm::Units::Stretch(1.0))
     }
 
     fn height(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -154,7 +154,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Stretch(1.0)),
             };
         }
-        return Some(morphorm::Units::Stretch(1.0));
+        Some(morphorm::Units::Stretch(1.0))
     }
 
     fn min_width(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -213,7 +213,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn right(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -228,7 +228,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn top(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -243,7 +243,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn bottom(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -258,7 +258,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn min_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -305,7 +305,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn child_right(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -320,7 +320,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn child_top(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -335,7 +335,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn child_bottom(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
@@ -350,7 +350,7 @@ impl<'a> morphorm::Node<'a> for WrappedIndex {
                 _ => Some(morphorm::Units::Auto),
             };
         }
-        return Some(morphorm::Units::Auto);
+        Some(morphorm::Units::Auto)
     }
 
     fn row_between(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
diff --git a/src/render/font/font_mapping.rs b/src/render/font/font_mapping.rs
index 786fccc..df015c6 100644
--- a/src/render/font/font_mapping.rs
+++ b/src/render/font/font_mapping.rs
@@ -35,23 +35,13 @@ use kayak_font::KayakFont;
 ///   # commands.insert_resource(context);
 /// }
 /// ```
-#[derive(Resource)]
+#[derive(Resource, Default)]
 pub struct FontMapping {
     font_ids: HashMap<Handle<KayakFont>, String>,
     font_handles: HashMap<String, Handle<KayakFont>>,
     new_fonts: Vec<String>,
 }
 
-impl Default for FontMapping {
-    fn default() -> Self {
-        Self {
-            font_ids: HashMap::default(),
-            font_handles: HashMap::default(),
-            new_fonts: Vec::new(),
-        }
-    }
-}
-
 impl FontMapping {
     /// Add a `KayakFont` to be tracked
     pub fn add(&mut self, key: impl Into<String>, handle: Handle<KayakFont>) {
@@ -69,22 +59,17 @@ impl FontMapping {
     }
 
     pub(crate) fn mark_all_as_new(&mut self) {
-        self.new_fonts
-            .extend(self.font_handles.keys().map(|key| key.clone()));
+        self.new_fonts.extend(self.font_handles.keys().cloned());
     }
 
     /// Get the handle for the given font name
     pub fn get_handle(&self, id: String) -> Option<Handle<KayakFont>> {
-        self.font_handles
-            .get(&id)
-            .and_then(|item| Some(item.clone()))
+        self.font_handles.get(&id).cloned()
     }
 
     /// Get the font name for the given handle
     pub fn get(&self, font: &Handle<KayakFont>) -> Option<String> {
-        self.font_ids
-            .get(font)
-            .and_then(|font_id| Some(font_id.clone()))
+        self.font_ids.get(font).cloned()
     }
 
     // pub(crate) fn add_loaded_to_kayak(
diff --git a/src/render/nine_patch/extract.rs b/src/render/nine_patch/extract.rs
index 5056597..7def341 100644
--- a/src/render/nine_patch/extract.rs
+++ b/src/render/nine_patch/extract.rs
@@ -31,13 +31,10 @@ pub fn extract_nine_patch(
         return vec![];
     }
 
-    let image_size = image
-        .and_then(|i| {
-            Some(Vec2::new(
+    let image_size = image.map(|i| Vec2::new(
                 i.texture_descriptor.size.width as f32,
                 i.texture_descriptor.size.height as f32,
             ))
-        })
         .unwrap()
         * dpi;
 
@@ -228,7 +225,7 @@ pub fn extract_nine_patch(
                 (image_size.x - border.right) / image_size.x,
                 middle_uv_max_y,
             )),
-            ..extracted_quad_template.clone()
+            ..extracted_quad_template
         },
     };
     extracted_quads.push(middle_quad);
diff --git a/src/render/texture_atlas/extract.rs b/src/render/texture_atlas/extract.rs
index 41eca02..3714aa7 100644
--- a/src/render/texture_atlas/extract.rs
+++ b/src/render/texture_atlas/extract.rs
@@ -26,19 +26,16 @@ pub fn extract_texture_atlas(
         _ => panic!(""),
     };
 
-    let image = images.get(&handle);
+    let image = images.get(handle);
 
     if image.is_none() {
         return vec![];
     }
 
-    let image_size = image
-        .and_then(|i| {
-            Some(Vec2::new(
+    let image_size = image.map(|i| Vec2::new(
                 i.texture_descriptor.size.width as f32,
                 i.texture_descriptor.size.height as f32,
             ))
-        })
         .unwrap()
         * dpi;
 
diff --git a/src/render/unified/mod.rs b/src/render/unified/mod.rs
index b592ed3..7efdec3 100644
--- a/src/render/unified/mod.rs
+++ b/src/render/unified/mod.rs
@@ -70,6 +70,6 @@ pub fn extract_baseline(
         1.0
     };
 
-    commands.insert_resource(window_size.clone());
+    commands.insert_resource(**window_size);
     commands.insert_resource(Dpi(dpi));
 }
diff --git a/src/render/unified/pipeline.rs b/src/render/unified/pipeline.rs
index 235d1c4..e1b8ff4 100644
--- a/src/render/unified/pipeline.rs
+++ b/src/render/unified/pipeline.rs
@@ -329,7 +329,7 @@ pub struct ExtractQuadBundle {
     pub extracted_quad: ExtractedQuad,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum UIQuadType {
     Quad,
     Text,
@@ -497,7 +497,7 @@ pub fn prepare_quads(
                 Quat::default(),
                 sprite_rect.min.extend(0.0),
             );
-            let final_position = (world * Vec3::from(*vertex_position).extend(1.0)).truncate();
+            let final_position = (world * (*vertex_position).extend(1.0)).truncate();
             sprite_meta.vertices.push(QuadVertex {
                 position: final_position.into(),
                 color,
@@ -560,7 +560,7 @@ pub fn queue_quads(
         for mut transparent_phase in views.iter_mut() {
             for (entity, quad) in extracted_sprites.iter_mut() {
                 if let Some(image_handle) = quad.image.as_ref() {
-                    if let Some(gpu_image) = gpu_images.get(&image_handle) {
+                    if let Some(gpu_image) = gpu_images.get(image_handle) {
                         image_bind_groups
                             .values
                             .entry(image_handle.clone_weak())
@@ -692,7 +692,7 @@ impl Draw<TransparentUI> for DrawUI {
 
             if let Some(image_handle) = extracted_quad.image.as_ref() {
                 if let Some(bind_group) = image_bind_groups.into_inner().values.get(image_handle) {
-                    pass.set_bind_group(3, &bind_group, &[]);
+                    pass.set_bind_group(3, bind_group, &[]);
                 } else {
                     pass.set_bind_group(3, &unified_pipeline.default_image.1, &[]);
                 }
diff --git a/src/styles/corner.rs b/src/styles/corner.rs
index 15f66f3..dfbfcdb 100644
--- a/src/styles/corner.rs
+++ b/src/styles/corner.rs
@@ -3,7 +3,7 @@ use std::ops::{Mul, MulAssign};
 /// A struct for defining properties related to the corners of widgets
 ///
 /// This is useful for things like border radii, etc.
-#[derive(Debug, Default, Copy, Clone, PartialEq)]
+#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
 pub struct Corner<T>
 where
     T: Copy + Default + PartialEq,
diff --git a/src/styles/edge.rs b/src/styles/edge.rs
index 84f1f0c..dabef3a 100644
--- a/src/styles/edge.rs
+++ b/src/styles/edge.rs
@@ -3,7 +3,7 @@ use std::ops::{Mul, MulAssign};
 /// A struct for defining properties related to the edges of widgets
 ///
 /// This is useful for things like borders, padding, etc.
-#[derive(Debug, Default, Copy, Clone, PartialEq)]
+#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
 pub struct Edge<T>
 where
     T: Copy + Default + PartialEq,
diff --git a/src/styles/options_ref.rs b/src/styles/options_ref.rs
index 2e2dc17..255b193 100644
--- a/src/styles/options_ref.rs
+++ b/src/styles/options_ref.rs
@@ -7,7 +7,7 @@ pub trait AsRefOption<T> {
 
 impl AsRefOption<KStyle> for KStyle {
     fn as_ref_option(&self) -> Option<&KStyle> {
-        Some(&self)
+        Some(self)
     }
 }
 
diff --git a/src/styles/style.rs b/src/styles/style.rs
index 9decc31..4439a2f 100644
--- a/src/styles/style.rs
+++ b/src/styles/style.rs
@@ -15,7 +15,7 @@ pub use super::Edge;
 use super::RenderCommand;
 
 /// Just a wrapper around bevy's CursorIcon so we can define a default.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub struct KCursorIcon(pub CursorIcon);
 
 impl Default for KCursorIcon {
@@ -27,7 +27,7 @@ impl Default for KCursorIcon {
 /// The base container of all style properties
 ///
 /// The default value for this enum is [`StyleProp::Unset`].
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum StyleProp<T: Default + Clone> {
     /// This prop is unset, meaning its actual value is not determined until style resolution,
     /// wherein it will be set to the property's default value.
@@ -593,7 +593,7 @@ mod tests {
     #[test]
     fn value_should_convert_to_property() {
         let expected_width = Units::Pixels(123.0);
-        let expected = StyleProp::Value(expected_width.clone());
+        let expected = StyleProp::Value(expected_width);
 
         let property: StyleProp<_> = expected_width.into();
 
diff --git a/src/tree.rs b/src/tree.rs
index 4a42130..ae02765 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -5,7 +5,7 @@ use std::iter::Rev;
 
 use crate::node::WrappedIndex;
 
-#[derive(Default, Debug, Clone, PartialEq)]
+#[derive(Default, Debug, Clone, PartialEq, Eq)]
 pub struct Tree {
     pub children: HashMap<WrappedIndex, Vec<WrappedIndex>>,
     pub parents: HashMap<WrappedIndex, WrappedIndex>,
@@ -68,8 +68,7 @@ impl Tree {
                 .remove(&index)
                 .unwrap_or_default()
                 .into_iter()
-                .map(|child| self.remove(child))
-                .flatten()
+                .flat_map(|child| self.remove(child))
                 .collect();
             if let Some(siblings) = self.children.get_mut(&parent) {
                 siblings.retain(|node| *node != index);
@@ -177,7 +176,7 @@ impl Tree {
             return Vec::new();
         }
 
-        DownwardIterator::new(&self, Some(self.root_node.unwrap()), true).collect::<Vec<_>>()
+        DownwardIterator::new(self, Some(self.root_node.unwrap()), true).collect::<Vec<_>>()
     }
 
     pub fn flatten_node(&self, root_node: WrappedIndex) -> Vec<WrappedIndex> {
@@ -185,7 +184,7 @@ impl Tree {
             return Vec::new();
         }
 
-        DownwardIterator::new(&self, Some(root_node), true).collect::<Vec<_>>()
+        DownwardIterator::new(self, Some(root_node), true).collect::<Vec<_>>()
     }
 
     pub fn flatten_node_up(&self, root_node: WrappedIndex) -> Vec<WrappedIndex> {
@@ -193,39 +192,35 @@ impl Tree {
             return Vec::new();
         }
 
-        UpwardIterator::new(&self, Some(root_node), true).collect::<Vec<_>>()
+        UpwardIterator::new(self, Some(root_node), true).collect::<Vec<_>>()
     }
 
     pub fn get_parent(&self, index: WrappedIndex) -> Option<WrappedIndex> {
         self.parents
-            .get(&index)
-            .map_or(None, |parent| Some(*parent))
+            .get(&index).copied()
     }
 
     pub fn get_first_child(&self, index: WrappedIndex) -> Option<WrappedIndex> {
-        self.children.get(&index).map_or(None, |children| {
+        self.children.get(&index).and_then(|children| {
             children
-                .first()
-                .map_or(None, |first_child| Some(*first_child))
+                .first().copied()
         })
     }
 
     pub fn get_last_child(&self, index: WrappedIndex) -> Option<WrappedIndex> {
-        self.children.get(&index).map_or(None, |children| {
-            children.last().map_or(None, |last_child| Some(*last_child))
+        self.children.get(&index).and_then(|children| {
+            children.last().copied()
         })
     }
 
     pub fn get_next_sibling(&self, index: WrappedIndex) -> Option<WrappedIndex> {
         if let Some(parent_index) = self.get_parent(index) {
-            self.children.get(&parent_index).map_or(None, |children| {
+            self.children.get(&parent_index).and_then(|children| {
                 children
                     .iter()
-                    .position(|child| *child == index)
-                    .map_or(None, |child_index| {
+                    .position(|child| *child == index).and_then(|child_index| {
                         children
-                            .get(child_index + 1)
-                            .map_or(None, |next_child| Some(*next_child))
+                            .get(child_index + 1).copied()
                     })
             })
         } else {
@@ -235,15 +230,13 @@ impl Tree {
 
     pub fn get_prev_sibling(&self, index: WrappedIndex) -> Option<WrappedIndex> {
         if let Some(parent_index) = self.get_parent(index) {
-            self.children.get(&parent_index).map_or(None, |children| {
+            self.children.get(&parent_index).and_then(|children| {
                 children
                     .iter()
-                    .position(|child| *child == index)
-                    .map_or(None, |child_index| {
+                    .position(|child| *child == index).and_then(|child_index| {
                         if child_index > 0 {
                             children
-                                .get(child_index - 1)
-                                .map_or(None, |prev_child| Some(*prev_child))
+                                .get(child_index - 1).copied()
                         } else {
                             None
                         }
@@ -292,14 +285,12 @@ impl Tree {
 
         let children_a = children_a
             .unwrap()
-            .into_iter()
-            .map(|i| *i)
+            .iter().copied()
             .enumerate()
             .collect::<Vec<(usize, WrappedIndex)>>();
         let children_b = children_b
             .unwrap()
-            .into_iter()
-            .map(|i| *i)
+            .iter().copied()
             .enumerate()
             .collect::<Vec<(usize, WrappedIndex)>>();
 
@@ -336,7 +327,7 @@ impl Tree {
             .collect::<Vec<_>>();
         child_changes.changes.extend(inserted_and_changed);
 
-        if child_changes.changes.len() > 0
+        if !child_changes.changes.is_empty()
             && child_changes.changes.iter().any(|a| {
                 child_changes
                     .changes
@@ -382,12 +373,10 @@ impl Tree {
                 if definitely_moved {
                     let change = if change[0] == Change::Unchanged {
                         vec![Change::Moved]
+                    } else if change[0] == Change::Updated {
+                        vec![Change::Moved, Change::Updated]
                     } else {
-                        if change[0] == Change::Updated {
-                            vec![Change::Moved, Change::Updated]
-                        } else {
-                            vec![Change::Moved]
-                        }
+                        vec![Change::Moved]
                     };
                     return (*id, *node, *parent_node, change);
                 }
@@ -507,12 +496,10 @@ impl Tree {
                 if definitely_moved {
                     let change = if change[0] == Change::Unchanged {
                         vec![Change::Moved]
+                    } else if change[0] == Change::Updated {
+                        vec![Change::Moved, Change::Updated]
                     } else {
-                        if change[0] == Change::Updated {
-                            vec![Change::Moved, Change::Updated]
-                        } else {
-                            vec![Change::Moved]
-                        }
+                        vec![Change::Moved]
                     };
                     return (*id, *node, *parent_node, change);
                 }
@@ -551,7 +538,7 @@ impl Tree {
             if has_changes {
                 let children_a = children_a.unwrap();
                 for child in children_a.iter() {
-                    self.parents.remove(&*child);
+                    self.parents.remove(child);
                 }
                 self.children.remove(&root_node);
             }
@@ -748,7 +735,7 @@ impl<'a> Iterator for DownwardIterator<'a> {
             }
         }
 
-        return self.current_node;
+        self.current_node
     }
 }
 
@@ -791,7 +778,7 @@ impl<'a> Iterator for UpwardIterator<'a> {
         }
 
         self.current_node = self.tree.get_parent(self.current_node?);
-        return self.current_node;
+        self.current_node
     }
 }
 
@@ -847,11 +834,7 @@ impl<'a> Hierarchy<'a> for Tree {
     fn is_first_child(&self, node: WrappedIndex) -> bool {
         if let Some(parent) = self.parent(node) {
             if let Some(first_child) = self.get_first_child(parent) {
-                if first_child == node {
-                    return true;
-                } else {
-                    return false;
-                }
+                return first_child == node
             }
         }
 
diff --git a/src/widget.rs b/src/widget.rs
index 8619111..bd4a21b 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -16,7 +16,7 @@ pub trait Widget: Send + Sync {
     }
 }
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct EmptyState;
 
 pub fn widget_update<Props: PartialEq + Component + Clone, State: PartialEq + Component + Clone>(
diff --git a/src/widget_context.rs b/src/widget_context.rs
index 393266e..d070384 100644
--- a/src/widget_context.rs
+++ b/src/widget_context.rs
@@ -140,7 +140,7 @@ impl KayakWidgetContext {
         if let Ok(mut hash_map) = self.index.try_write() {
             if hash_map.contains_key(&parent) {
                 let index = hash_map.get_mut(&parent).unwrap();
-                let current_index = index.clone();
+                let current_index = *index;
                 *index += 1;
                 return current_index;
             } else {
@@ -199,7 +199,7 @@ impl KayakWidgetContext {
             if let Ok(mut tree) = self.order_tree.try_write() {
                 tree.add(
                     WrappedIndex(entity.unwrap()),
-                    parent_id.and_then(|parent| Some(WrappedIndex(parent))),
+                    parent_id.map(WrappedIndex),
                 )
             }
         }
@@ -223,7 +223,7 @@ impl KayakWidgetContext {
         if let Ok(mut tree) = self.new_tree.write() {
             tree.add(
                 WrappedIndex(entity),
-                parent.map(|parent| WrappedIndex(parent)),
+                parent.map(WrappedIndex),
             );
         }
     }
diff --git a/src/widget_state.rs b/src/widget_state.rs
index 6762396..7fe6b80 100644
--- a/src/widget_state.rs
+++ b/src/widget_state.rs
@@ -1,7 +1,7 @@
 use std::sync::{Arc, RwLock};
 
 use bevy::{
-    prelude::{Commands, Component, Entity},
+    prelude::{BuildChildren, Commands, Component, Entity},
     utils::HashMap,
 };
 
@@ -23,9 +23,14 @@ impl WidgetState {
             if mapping.contains_key(&widget_entity) {
                 *mapping.get(&widget_entity).unwrap()
             } else {
-                let state_entity = commands.spawn(initial_state).id();
-                mapping.insert(widget_entity, state_entity);
-                state_entity
+                let mut state_entity = None;
+                commands
+                    .entity(widget_entity)
+                    .with_children(|child_builder| {
+                        state_entity = Some(child_builder.spawn(initial_state).id());
+                        mapping.insert(widget_entity, state_entity.unwrap());
+                    });
+                state_entity.expect("State entity did not spawn!")
             }
         } else {
             panic!("Couldn't get mapping lock!");
diff --git a/src/widgets/app.rs b/src/widgets/app.rs
index 5d80ad7..7227042 100644
--- a/src/widgets/app.rs
+++ b/src/widgets/app.rs
@@ -13,7 +13,7 @@ use crate::{
 
 use super::ClipBundle;
 
-#[derive(Component, Default, Clone, PartialEq)]
+#[derive(Component, Default, Clone, PartialEq, Eq)]
 pub struct KayakApp;
 
 impl Widget for KayakApp {}
diff --git a/src/widgets/background.rs b/src/widgets/background.rs
index 63f0cba..c214604 100644
--- a/src/widgets/background.rs
+++ b/src/widgets/background.rs
@@ -9,7 +9,7 @@ use crate::{
     widget::Widget,
 };
 
-#[derive(Component, PartialEq, Clone, Default)]
+#[derive(Component, PartialEq, Eq, Clone, Default)]
 pub struct Background;
 
 impl Widget for Background {}
diff --git a/src/widgets/button.rs b/src/widgets/button.rs
index 419a5a7..533e927 100644
--- a/src/widgets/button.rs
+++ b/src/widgets/button.rs
@@ -47,7 +47,7 @@ impl Default for KButtonBundle {
 
 impl Widget for KButton {}
 
-#[derive(Component, Default, Debug, Clone, PartialEq)]
+#[derive(Component, Default, Debug, Clone, PartialEq, Eq)]
 pub struct ButtonState {
     hovering: bool,
 }
diff --git a/src/widgets/clip.rs b/src/widgets/clip.rs
index 386bae9..3f3e3e5 100644
--- a/src/widgets/clip.rs
+++ b/src/widgets/clip.rs
@@ -8,7 +8,7 @@ use crate::{
     widget::Widget,
 };
 
-#[derive(Component, PartialEq, Clone, Default)]
+#[derive(Component, PartialEq, Eq, Clone, Default)]
 pub struct Clip;
 
 impl Widget for Clip {}
diff --git a/src/widgets/element.rs b/src/widgets/element.rs
index 64507d7..d5663b3 100644
--- a/src/widgets/element.rs
+++ b/src/widgets/element.rs
@@ -9,7 +9,7 @@ use crate::{
     widget::Widget,
 };
 
-#[derive(Component, PartialEq, Clone, Default)]
+#[derive(Component, PartialEq, Eq, Clone, Default)]
 pub struct Element;
 
 impl Widget for Element {}
@@ -39,7 +39,7 @@ impl Default for ElementBundle {
 }
 
 pub fn element_render(
-    In((mut widget_context, entity)): In<(KayakWidgetContext, Entity)>,
+    In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
     _: Commands,
     mut query: Query<(&mut KStyle, &KChildren)>,
 ) -> bool {
@@ -50,7 +50,7 @@ pub fn element_render(
                 render_command: StyleProp::Value(RenderCommand::Layout),
                 ..Default::default()
             });
-        children.process(&mut widget_context, Some(entity));
+        children.process(&widget_context, Some(entity));
     }
     true
 }
diff --git a/src/widgets/image.rs b/src/widgets/image.rs
index eb85fa1..fee9429 100644
--- a/src/widgets/image.rs
+++ b/src/widgets/image.rs
@@ -9,7 +9,7 @@ use crate::{
 
 /// Renders a bevy image asset within the GUI
 /// The rendered image respects the styles.
-#[derive(Component, PartialEq, Clone, Default)]
+#[derive(Component, PartialEq, Eq, Clone, Default)]
 pub struct KImage(pub Handle<bevy::prelude::Image>);
 
 impl Widget for KImage {}
diff --git a/src/widgets/scroll/scroll_box.rs b/src/widgets/scroll/scroll_box.rs
index 60eb4df..7803295 100644
--- a/src/widgets/scroll/scroll_box.rs
+++ b/src/widgets/scroll/scroll_box.rs
@@ -228,11 +228,10 @@ pub fn scroll_box_render(
                                             disabled: disable_horizontal,
                                             horizontal: true,
                                             thickness: hori_thickness,
-                                            thumb_color: thumb_color,
+                                            thumb_color,
                                             thumb_styles: thumb_styles.clone(),
-                                            track_color: track_color,
+                                            track_color,
                                             track_styles: track_styles.clone(),
-                                            ..Default::default()
                                         }}
                                     />
                                 }
@@ -244,10 +243,10 @@ pub fn scroll_box_render(
                                     scrollbar_props={ScrollBarProps {
                                         disabled: disable_vertical,
                                         thickness: hori_thickness,
-                                        thumb_color: thumb_color.clone(),
-                                        thumb_styles: thumb_styles.clone(),
-                                        track_color: track_color,
-                                        track_styles: track_styles.clone(),
+                                        thumb_color,
+                                        thumb_styles,
+                                        track_color,
+                                        track_styles,
                                         ..Default::default()
                                     }}
                                 />
diff --git a/src/widgets/scroll/scroll_content.rs b/src/widgets/scroll/scroll_content.rs
index 4f2a2fe..4c11937 100644
--- a/src/widgets/scroll/scroll_content.rs
+++ b/src/widgets/scroll/scroll_content.rs
@@ -13,7 +13,7 @@ use crate::{
 
 use super::scroll_context::ScrollContext;
 
-#[derive(Component, Default, PartialEq, Clone)]
+#[derive(Component, Default, PartialEq, Eq, Clone)]
 pub struct ScrollContentProps;
 
 impl Widget for ScrollContentProps {}
diff --git a/src/widgets/scroll/scroll_context.rs b/src/widgets/scroll/scroll_context.rs
index 0c249dc..5ae99ca 100644
--- a/src/widgets/scroll/scroll_context.rs
+++ b/src/widgets/scroll/scroll_context.rs
@@ -23,7 +23,7 @@ pub struct ScrollContext {
 }
 
 #[non_exhaustive]
-#[derive(Debug, Copy, Clone, PartialEq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum ScrollMode {
     /// Clamps the scroll offset to stay within the scroll range
     Clamped,
diff --git a/src/widgets/text_box.rs b/src/widgets/text_box.rs
index bcce5c1..ebb5631 100644
--- a/src/widgets/text_box.rs
+++ b/src/widgets/text_box.rs
@@ -25,7 +25,7 @@ use crate::{
 use super::ElementBundle;
 
 /// Props used by the [`TextBox`] widget
-#[derive(Component, PartialEq, Default, Debug, Clone)]
+#[derive(Component, PartialEq, Eq, Default, Debug, Clone)]
 pub struct TextBoxProps {
     /// If true, prevents the widget from being focused (and consequently edited)
     pub disabled: bool,
diff --git a/src/widgets/window.rs b/src/widgets/window.rs
index 6ccf5ba..7a2d88b 100644
--- a/src/widgets/window.rs
+++ b/src/widgets/window.rs
@@ -93,8 +93,8 @@ pub fn window_render(
             None
         };
 
-        window_style.z_index = if z_index.is_some() {
-            StyleProp::Value(z_index.unwrap() as i32 * 1000)
+        window_style.z_index = if let Some(z_index) = z_index {
+            StyleProp::Value(z_index as i32 * 1000)
         } else {
             StyleProp::Default
         };
@@ -191,7 +191,7 @@ pub fn window_render(
                     >
                         <TextWidgetBundle
                             text={TextProps {
-                                content: title.clone(),
+                                content: title,
                                 size: 14.0,
                                 user_styles: KStyle {
                                     top: Units::Stretch(1.0).into(),
diff --git a/src/widgets/window_context_provider.rs b/src/widgets/window_context_provider.rs
index 216a597..037707e 100644
--- a/src/widgets/window_context_provider.rs
+++ b/src/widgets/window_context_provider.rs
@@ -4,7 +4,7 @@ use crate::{
     children::KChildren, context::WidgetName, prelude::KayakWidgetContext, widget::Widget,
 };
 
-#[derive(Component, Default, Debug, Clone, PartialEq)]
+#[derive(Component, Default, Debug, Clone, PartialEq, Eq)]
 pub struct WindowContext {
     order: Vec<Entity>,
     z_indices: HashMap<Entity, usize>,
@@ -43,12 +43,12 @@ impl WindowContext {
     }
 }
 
-#[derive(Component, Default, Debug, Clone, PartialEq)]
+#[derive(Component, Default, Debug, Clone, PartialEq, Eq)]
 pub struct WindowContextProvider;
 
 impl Widget for WindowContextProvider {}
 
-#[derive(Bundle, Debug, Clone, PartialEq)]
+#[derive(Bundle, Debug, Clone, PartialEq, Eq)]
 pub struct WindowContextProviderBundle {
     pub context_provider: WindowContextProvider,
     pub children: KChildren,
-- 
GitLab