Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#[component] macro #92

Merged
merged 10 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions docs/markdown/advanced/higher_order_components.md

This file was deleted.

14 changes: 6 additions & 8 deletions docs/markdown/basics/components.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Components

Components in `maple` are simply functions that return `TemplateResult<G>`.
They receive their props through function arguments.
Components in `maple` are structs that implement `Component`. A component can automatically be
created with the `#[component(ComponentName<G>)]` attribute on a function.

Components receive their props through function arguments.

For components to automatically react to prop changes, they should accept a prop with type `StateHandle<T>` and call the function in the `template!` to subscribe to the state.
A `StateHandle<T>` is just a readonly `Signal<T>`.
Expand All @@ -11,14 +13,10 @@ Getting a `StateHandle<T>` from a `Signal<T>` is easy. Just call the `.handle()`
Here is an example of a simple component that displays the value of its prop:

```rust
// This is temporary and will later be removed.
// Currently, the template! macro assumes that all
// components start with an uppercase character.
#![allow(non_snake_case)]

use maple_core::prelude::*;

fn MyComponent<G: GenericNode>(value: StateHandle<i32>) -> TemplateResult<G> {
#[component(MyComponent<G>)]
fn my_component(value: StateHandle<i32>) -> TemplateResult<G> {
template! {
div(class="my-component") {
"Value: " (value.get())
Expand Down
3 changes: 2 additions & 1 deletion docs/src/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ extern "C" {
fn highlight_all();
}

pub fn Content<G: GenericNode>() -> TemplateResult<G> {
#[component(Content<G>)]
pub fn content() -> TemplateResult<G> {
let location = web_sys::window()
.unwrap()
.document()
Expand Down
3 changes: 2 additions & 1 deletion docs/src/header.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use maple_core::prelude::*;

pub fn Header<G: GenericNode>() -> TemplateResult<G> {
#[component(Header<G>)]
pub fn header() -> TemplateResult<G> {
template! {
header {
nav(class="navbar navbar-expand-sm navbar-dark bg-dark") {
Expand Down
3 changes: 2 additions & 1 deletion docs/src/index.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use maple_core::prelude::*;

pub fn Index<G: GenericNode>() -> TemplateResult<G> {
#[component(Index<G>)]
pub fn index() -> TemplateResult<G> {
template! {
div {
h1 {
Expand Down
5 changes: 2 additions & 3 deletions docs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#![allow(non_snake_case)]

mod content;
mod header;
mod index;
mod sidebar;

use maple_core::prelude::*;

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let location = web_sys::window()
.unwrap()
.document()
Expand Down
6 changes: 2 additions & 4 deletions docs/src/sidebar.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use maple_core::prelude::*;

pub fn Sidebar<G: GenericNode>() -> TemplateResult<G> {
#[component(Sidebar<G>)]
pub fn sidebar() -> TemplateResult<G> {
template! {
div(class="p-3 bg-white", style="min-width: 180px") {
ul(class="list-unstyled ps-0") {
Expand Down Expand Up @@ -69,9 +70,6 @@ pub fn Sidebar<G: GenericNode>() -> TemplateResult<G> {
a(class="btn btn-sm btn-light btn-block", href="/advanced/js_interop") {
"JS Interop"
}
a(class="btn btn-sm btn-light btn-block", href="/advanced/higher_order_components") {
"Higher-Order Components"
}
}
}
li(class="mb-1") {
Expand Down
8 changes: 4 additions & 4 deletions examples/components/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#![allow(non_snake_case)]

use maple_core::prelude::*;

fn MyComponent<G: GenericNode>(num: StateHandle<i32>) -> TemplateResult<G> {
#[component(MyComponent<G>)]
fn my_component(num: StateHandle<i32>) -> TemplateResult<G> {
template! {
div(class="my-component") {
"My component"
Expand All @@ -14,7 +13,8 @@ fn MyComponent<G: GenericNode>(num: StateHandle<i32>) -> TemplateResult<G> {
}
}

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let state = Signal::new(1);

let increment = cloned!((state) => move |_| {
Expand Down
5 changes: 2 additions & 3 deletions examples/counter/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#![allow(non_snake_case)]

use maple_core::prelude::*;

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let counter = Signal::new(0);

create_effect(cloned!((counter) => move || {
Expand Down
5 changes: 2 additions & 3 deletions examples/hello/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#![allow(non_snake_case)]

use maple_core::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{Event, HtmlInputElement};

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let name = Signal::new(String::new());

let handle_change = cloned!((name) => move |event: Event| {
Expand Down
5 changes: 2 additions & 3 deletions examples/ssr/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#![allow(non_snake_case)]

use maple_core::prelude::*;

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let name = Signal::new(String::new());

let handle_change = move |_| unreachable!();
Expand Down
3 changes: 2 additions & 1 deletion examples/todomvc/src/copyright.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use maple_core::prelude::*;

pub fn Copyright<G: GenericNode>() -> TemplateResult<G> {
#[component(Copyright<G>)]
pub fn copyright() -> TemplateResult<G> {
template! {
footer(class="info") {
p { "Double click to edit a todo" }
Expand Down
5 changes: 3 additions & 2 deletions examples/todomvc/src/footer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use maple_core::prelude::*;

use crate::{AppState, Filter};

pub fn Footer<G: GenericNode>(app_state: AppState) -> TemplateResult<G> {
#[component(Footer<G>)]
pub fn footer(app_state: AppState) -> TemplateResult<G> {
let items_text = cloned!((app_state) => move || {
match app_state.todos_left() {
1 => "item",
Expand All @@ -24,7 +25,7 @@ pub fn Footer<G: GenericNode>(app_state: AppState) -> TemplateResult<G> {
span { " " (items_text()) " left" }
}
ul(class="filters") {
Indexed(IndexedProps {
Indexed<_, _>(IndexedProps {
iterable: Signal::new(vec![Filter::All, Filter::Active, Filter::Completed]).handle(),
template: cloned!((app_state2) => move |filter| {
let selected = cloned!((app_state2) => move || filter == *app_state2.filter.get());
Expand Down
3 changes: 2 additions & 1 deletion examples/todomvc/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use web_sys::{Event, HtmlInputElement, KeyboardEvent};

use crate::AppState;

pub fn Header<G: GenericNode>(app_state: AppState) -> TemplateResult<G> {
#[component(Header<G>)]
pub fn header(app_state: AppState) -> TemplateResult<G> {
let value = Signal::new(String::new());

let input_ref = NodeRef::<G>::new();
Expand Down
10 changes: 9 additions & 1 deletion examples/todomvc/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ use web_sys::{Event, HtmlInputElement, KeyboardEvent};

use crate::{AppState, Todo};

pub fn Item<G: GenericNode>(todo: Signal<Todo>, app_state: AppState) -> TemplateResult<G> {
pub struct ItemProps {
pub todo: Signal<Todo>,
pub app_state: AppState,
}

#[component(Item<G>)]
pub fn item(props: ItemProps) -> TemplateResult<G> {
let ItemProps { todo, app_state } = props;

let title = cloned!((todo) => move || todo.get().title.clone());
let completed = create_selector(cloned!((todo) => move || todo.get().completed));
let id = todo.get().id;
Expand Down
7 changes: 4 additions & 3 deletions examples/todomvc/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use web_sys::HtmlInputElement;

use crate::{AppState, Filter};

pub fn List<G: GenericNode>(app_state: AppState) -> TemplateResult<G> {
#[component(List<G>)]
pub fn list(app_state: AppState) -> TemplateResult<G> {
let todos_left = create_selector(cloned!((app_state) => move || {
app_state.todos_left()
}));
Expand Down Expand Up @@ -40,10 +41,10 @@ pub fn List<G: GenericNode>(app_state: AppState) -> TemplateResult<G> {
label(for="toggle-all")

ul(class="todo-list") {
Keyed(KeyedProps {
Keyed<_, _, _, _>(KeyedProps {
iterable: filtered_todos,
template: move |todo| template! {
crate::item::Item(todo, app_state.clone())
crate::item::Item(crate::item::ItemProps { todo, app_state: app_state.clone() })
},
key: |todo| todo.get().id,
})
Expand Down
5 changes: 2 additions & 3 deletions examples/todomvc/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![allow(non_snake_case)]

mod copyright;
mod footer;
mod header;
Expand Down Expand Up @@ -132,7 +130,8 @@ impl Filter {

const KEY: &str = "todos-maple";

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let local_storage = web_sys::window()
.unwrap()
.local_storage()
Expand Down
5 changes: 2 additions & 3 deletions examples/tweened/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#![allow(non_snake_case)]

use std::time::Duration;

use maple_core::reactive::Tweened;
use maple_core::{easing, prelude::*};

fn App<G: GenericNode>() -> TemplateResult<G> {
#[component(App<G>)]
fn app() -> TemplateResult<G> {
let progress = Tweened::new([0.0, 1.0], Duration::from_millis(250), easing::quad_out);
let progress0 = progress.clone();
let progress1 = progress.clone();
Expand Down
42 changes: 0 additions & 42 deletions maple-core-macro/src/component.rs

This file was deleted.

Loading