### Serve Sycamore Example Locally with Trunk Source: https://github.com/sycamore-rs/sycamore/blob/main/README.md Command to build and serve a Sycamore example application locally using Trunk. It navigates to the example directory and starts a development server, typically accessible at http://localhost:8080. ```bash cd examples/todomvc trunk serve ``` -------------------------------- ### Build and Serve Example with Trunk Source: https://github.com/sycamore-rs/sycamore/blob/main/examples/README.md Builds and serves a Sycamore RS example locally using the Trunk build tool. Requires navigating to the example directory and running `trunk serve`. Accessible via `localhost:8080`. ```bash cd examples/todomvc trunk serve ``` -------------------------------- ### Install Trunk Build Tool Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Installs Trunk, the recommended build tool for Sycamore projects, using Homebrew, release binaries, or Cargo. Trunk handles building Rust WASM apps. ```bash # Install via homebrew on Mac, Linux or Windows (WSL). brew install trunk # Install a release binary (great for CI). # You will need to specify a value for ${VERSION}. # wget -qO- https://github.com/thedodd/trunk/releases/download/${VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- # Install via cargo. cargo install --locked trunk ``` -------------------------------- ### Serve Sycamore App Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Starts a development server using Trunk, which builds your Sycamore app and automatically recompiles it on source file changes. ```bash trunk serve ``` -------------------------------- ### Complete Sycamore App Example Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/adding-state.md Provides a full example of a Sycamore application demonstrating reactive state management, derived state, event handling, and rendering within the `view!` macro. It includes the necessary `use` statements and the `main` function for rendering. ```rust use sycamore::prelude::*; #[component] fn App() -> View { let mut counter = create_signal(1); let doubled = create_memo(move || counter.get() * 2); let increment = move |_| counter += 1; view! { button(on:click=increment) { "Increment" } p { "Count:" (counter) } p { "Doubled: " (doubled) } } } fn main() { sycamore::render(App); } ``` -------------------------------- ### Run Package-Specific Tests Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/contributing.md Example of how to navigate into a specific package directory (e.g., `sycamore-reactive`) and run its tests. ```bash cd packages/sycamore-reactive cargo test --all-features ``` -------------------------------- ### New Builder Syntax for Sycamore Views Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Sycamore v0.9 introduces a new builder syntax for creating views, offering improved type checking for attributes and a more streamlined API. This example contrasts the old and new ways of constructing complex UI elements, including dynamic content and event binding. ```rust // Old div() .c(h1() .t("Hello ") .dyn_if( move || !name.with(String::is_empty), move || span().dyn_t(move || name.get_clone()), move || span().t("World") ) .t("!")) .c(input().bind_value(name)) .view(); // New div() .children(( h1().children(( "Hello ", move || { if !name.with(String::is_empty) { span().children(move || name.get_clone()) } else { span().children("World") } }, "!", )), input().bind(bind::value, name), )) .into(); ``` -------------------------------- ### Add WASM Target for Rust Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Adds the `wasm32-unknown-unknown` target to your Rust installation, which is necessary for compiling Rust code to WebAssembly. ```bash rustup target add wasm32-unknown-unknown ``` -------------------------------- ### Set Up Rust Nightly Toolchain Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/contributing.md Commands to install and set the Rust nightly toolchain as the default for the Sycamore project, which is recommended for development. ```bash rustup toolchain add nightly rustup override set nightly ``` -------------------------------- ### Render Nested Views with view! Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Illustrates nesting HTML elements within the view! macro to create structured UI. This example shows how to wrap elements in a div container for better organization. ```rust view! { div { h1 { "Hello, world!" } p { "This is my first Sycamore app" } } } ``` -------------------------------- ### Run Sycamore Micro-benchmarks Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/contributing.md Executes the micro-benchmarks for Sycamore located in the `packages/tools/bench` directory. This command requires Rust and Cargo to be installed and configured. ```shell cargo bench ``` -------------------------------- ### Sycamore SSR Local Execution Source: https://github.com/sycamore-rs/sycamore/blob/main/examples/ssr/index.html Instructions for running the Sycamore Server-Side Rendering (SSR) example locally. This example is not compatible with WebAssembly (Wasm) and requires a local Rust environment. ```Shell cargo run ``` -------------------------------- ### Sycamore Rust Todo App: Full Code Example Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/todo-app.md Complete Rust code for a Sycamore todo app. Demonstrates `TodoItem`, `TodoList`, `TodoInput` components, signal-based state management, event handling (keyboard, click), and local storage persistence. ```rust use serde::{Deserialize, Serialize}; use sycamore::prelude::*; use web_sys::KeyboardEvent; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] struct Todo { task: Signal, completed: Signal, id: u32, } #[component(inline_props)] fn TodoItem(todo: Todo, remove_todo: F) -> View where F: Fn(u32) + Copy + 'static, { on_cleanup(move || { todo.task.dispose(); todo.completed.dispose(); }); // We are using inline styles here which is generally not considered best practice. // In real app, you would probably use an external CSS file. let style = move || { if todo.completed.get() { "text-decoration: line-through;" } else { "" } }; let toggle_completed = move |_| todo.completed.set(!todo.completed.get()); let remove_todo = move |_| remove_todo(todo.id); let is_editing = create_signal(false); let start_editing = move |_| is_editing.set(true); let on_keydown = move |ev: KeyboardEvent| { if ev.key() == "Enter" && !todo.task.with(String::is_empty) { is_editing.set(false); } }; view! { li { span(style=style, on:click=toggle_completed) { (if is_editing.get() { view! { input(bind:value=todo.task, on:keydown=on_keydown) } } else { view! { (todo.task) } }) } button(on:click=start_editing, disabled=is_editing.get()) { "Edit Task" } button(on:click=remove_todo) { "Remove" } } } } #[component(inline_props)] fn TodoList(#[prop(setter(into))] todos: MaybeDyn>, remove_todo: F) -> View where F: Fn(u32) + Copy + 'static, { view! { ul { Keyed( list=todos, view=move |todo| view! { TodoItem(todo=todo, remove_todo=remove_todo) }, key=|todo| todo.id, ) } } } #[component(inline_props)] fn TodoInput(add_todo: F) -> View where F: Fn(String) + 'static, { let input = create_signal(String::new()); let on_keydown = move |ev: KeyboardEvent| { if ev.key() == "Enter" && !input.with(String::is_empty) { add_todo(input.get_clone()); input.set(String::new()); } }; view! { div { "New Todo: " input(bind:value=input, on:keydown=on_keydown) } } } #[component] fn App() -> View { // Initialize application state from localStorage. let local_storage = window() .local_storage() .unwrap() .expect("user has not enabled localStorage"); let todos: Signal> = if let Ok(Some(app_state)) = local_storage.get_item("todos") { serde_json::from_str(&app_state).unwrap_or_default() } else { Default::default() }; // Set up an effect that runs whenever app_state.todos changes to save the todos to // localStorage. create_effect(move || { todos.with(|todos| { // Also track all nested signals. for todo in todos { todo.task.track(); todo.completed.track(); } local_storage .set_item("todos", &serde_json::to_string(todos).unwrap()) .unwrap(); }); }); let next_id = create_signal(0); // `replace(...)` is the same as `set(...)` but returns the previous value. let get_next_id = move || next_id.replace(next_id.get() + 1); let add_todo = move |task| { todos.update(|todos| { todos.push(Todo { task: create_signal(task), completed: create_signal(false), id: get_next_id(), }) }) }; let remove_todo = move |id| todos.update(|todos| todos.retain(|todo| todo.id != id)); view! { TodoInput(add_todo=add_todo) TodoList(todos=todos, remove_todo=remove_todo) } } fn main() { sycamore::render(App); } ``` -------------------------------- ### Sycamore Builder API Example Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/posts/announcing-v0-7-0.md Demonstrates the experimental Builder API for Sycamore, allowing application development using plain Rust functions instead of the view! macro. This API is still under development and may have compatibility issues with hydration. ```rust let name = Signal::new(String::new()); div() .child( h1().text("Hello ") .dyn_child(cloned!((name) => move || { if *create_selector(cloned!(name => move || !name.get().is_empty())).get() { span() .dyn_text(cloned!(name => move || name.get().to_string())) .build() } else { span().text("World").build() } })) .text("!") .build(), ) .child(input().bind_value(name).build()) .build() ``` -------------------------------- ### Convert Signals directly to views in Sycamore Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Illustrates the simplification of converting Sycamore signals directly into views within the `view!` macro. This removes the need for explicit `.get()` calls, making the syntax cleaner. ```rust // No more need to do this: // view! { // (signal.get()) // } // Now, you can just write: view! { (signal) } ``` -------------------------------- ### Define Sycamore Component in Rust Source: https://github.com/sycamore-rs/sycamore/blob/main/README.md Example of defining a simple Sycamore component named 'Hello' that renders a paragraph with 'Hello World!'. This demonstrates the basic structure for creating UI elements in Sycamore using Rust and its `view!` macro. ```rust #[component] fn Hello() -> View { view! { p { "Hello World!" } } } ``` -------------------------------- ### Run WASM Tests with wasm-pack Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/contributing.md Instructions to run WebAssembly tests using `wasm-pack`. Requires `wasm-pack` to be installed. The `--chrome` flag specifies the browser to use. ```bash cd packages/sycamore wasm-pack test --chrome ``` -------------------------------- ### Full Context Example: Provide and Use Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/contexts.md Demonstrates the complete flow: providing a context value at a higher level and then accessing it within a child component. Ensure the context value is reactive if state changes are needed. ```rust provide_context::(DarkMode(create_signal(false)) ); view! { ChildComponent {} } ``` -------------------------------- ### Handle Rust keywords ref and type in view! macro Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Explains how to use the `r#` prefix for Rust keywords like `ref` and `type` when they are used as identifiers within the Sycamore `view!` macro, aligning with Rust's keyword handling. ```rust view! { // Previously: ref=..., type=... // Now: r#ref=..., r#type=... } ``` -------------------------------- ### Component Arguments and Children Syntax (Rust) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-7-to-0-8.md Shows the updated syntax for passing arguments and children to components in Sycamore v0.8. The syntax now aligns with how arguments are passed to elements, using keyword arguments and a block for children. ```rust // Old v0.7 syntax. view! { MyComponent(MyProps { foo: true, bar: "abc", children: view! { ... } }) } // New v0.8 syntax. view! { cx, MyComponent(foo=true, bar="abc") { ... } } ``` -------------------------------- ### Update View Backend Generics in Sycamore Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Sycamore v0.9 simplifies the view backend by removing generics for isomorphic rendering. It now uses target detection to automatically select the DOM backend for `wasm32` targets and the SSR backend otherwise. This example shows the transition from generic `View` to `View`. ```rust // Old #[component(inline_props)] fn Component<'a, G: Html>(cx: Scope<'a>, value: &'a ReadSignal) -> View { ... } // New #[component(inline_props)] fn Component(value: ReadSignal) -> View { ... } ``` -------------------------------- ### Create New Sycamore Project Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Creates a new Rust project using Cargo and navigates into the project directory. This sets up the basic file structure for your application. ```bash cargo new hello-sycamore cd hello-sycamore ``` -------------------------------- ### Use .get_clone() for Non-Copy Signals in Sycamore Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md In Sycamore v0.9, signals no longer automatically wrap values in `Rc`. For non-`Copy` types, you must now explicitly use `.get_clone()` to obtain a owned value or use `.with(|value| ...)` for borrowing. This example shows accessing `i32` (Copy) and `String` (non-Copy) signals. ```rust let number: Signal = create_signal(123); let string: Signal = create_signal("Hello, Sycamore!".to_string()); // `i32` implements `Copy`. let _: i32 = number.get(); // `String` does not implement `Copy` but implements `Clone`. let _: String = string.get_clone(); ``` -------------------------------- ### Sycamore Hello World App Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Renders a simple 'Hello, world!' text node using Sycamore. The `sycamore::render` function takes a closure that returns a UI `View`. ```rust use sycamore::prelude::*; fn main() { sycamore::render(|| "Hello, world!".into()); } ``` -------------------------------- ### Render Basic View with view! Macro Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Demonstrates how to render simple HTML elements like h1 and p using Sycamore's view! macro and the sycamore::render function. This is the foundational step for creating UI in Sycamore. ```rust sycamore::render(|| view! { h1 { "Hello, world!" } p { "This is my first Sycamore app" } }); ``` -------------------------------- ### Define and Render Basic Sycamore Component Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Explains how to define a reusable UI component using the #[component] attribute and render it within the main function. Components help in structuring and organizing application code. ```rust #[component] fn App() -> View { view! { div { h1 { "Hello, world!" } p { "This is my first Sycamore app" } } } } fn main() { sycamore::render(App); } ``` -------------------------------- ### Basic HTML for Trunk Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md A minimal HTML file required for Trunk to build your Sycamore app to WebAssembly. It serves as the entry point for the web application. ```html ``` -------------------------------- ### Add WASM Target Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/contributing.md Command to add the `wasm32-unknown-unknown` target to your Rust installation, necessary for WebAssembly development within Sycamore. ```bash rustup target add wasm32-unknown-unknown --toolchain nightly ``` -------------------------------- ### Use Components within Views Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Demonstrates how custom components can be used at the top level or nested within other views using the view! macro. This promotes code reusability and modularity. ```rust #[component] fn HelloWorld() -> View { view! { p { "Hello, world!" } } } #[component] fn App() -> View { view! { // Components can be at the top-level of a view. HelloWorld() // Or they can be nested. div { HelloWorld() } } } ``` -------------------------------- ### Add Dependencies for Local Storage Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/todo-app.md Lists the necessary Cargo dependencies to enable local storage persistence. This includes `serde` for serialization, `serde_json` for JSON handling, `web-sys` for browser API access, and Sycamore with the `serde` feature. ```bash cargo add serde -F derive cargo add serde_json cargo add web-sys -F Storage cargo add sycamore -F serde ``` -------------------------------- ### Sycamore SSR CSS Styling Source: https://github.com/sycamore-rs/sycamore/blob/main/examples/ssr/index.html Defines the font family for the SSR body in Sycamore. This CSS is applied to the main content area for consistent typography. ```CSS body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } ``` -------------------------------- ### Empty Elements Syntax (Rust) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-7-to-0-8.md Illustrates the requirement for empty elements (like `br` or `img`) to be followed by an empty block `{}` in the `view!` macro in Sycamore v0.8. ```rust // Old v0.7 syntax. view! { br } // New v0.8 syntax. view! { cx, br {} } ``` -------------------------------- ### Rename iterable to list in Sycamore Indexed/Keyed Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Demonstrates the renaming of the `iterable` prop to `list` for Sycamore's `Indexed` and `Keyed` components. This change improves clarity and consistency in the framework. ```rust // Old view! { Indexed( iterable=..., view=..., ) } // New view! { Indexed( list=..., view=..., ) } ``` -------------------------------- ### Clone Sycamore Repository Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/contributing.md Instructions to fork and clone the Sycamore repository to your local machine to begin development. ```bash git clone https://github.com//sycamore cd sycamore ``` -------------------------------- ### Keyed/Indexed Props Syntax Update (Rust) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-7-to-0-8.md Details the renaming of the `template` prop to `view` and the updated syntax for passing props to `Keyed` and `Indexed` components in Sycamore v0.8. ```rust // Old v0.7 syntax. Keyed(KeyedProps { iterable: count.handle(), template: |x| view! { li { (x) } }, key: |x| *x, }) // New 0.8 syntax. Keyed( iterable=count, view=|cx, x| view! { cx, li { (x) } }, key=|x| *x, ) ``` -------------------------------- ### Define Context Struct Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/contexts.md Define a struct to hold your context data. It's common to wrap signals within the context type to make the shared state reactive. This example shows a `DarkMode` context. ```rust #[derive(Clone, Copy, PartialEq, Eq)] struct DarkMode(Signal); impl DarkMode { fn is_enabled(self) -> bool { self.0.get() } fn toggle(self) { self.0.set(!self.0.get()); } } ``` -------------------------------- ### Sycamore Rust Data Binding Example Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/data-binding.md Demonstrates binding a Sycamore `Signal` to an input element's `value` property using the `bind:` directive. Updates are synchronized bidirectionally between the signal and the DOM element. ```rust use sycamore::prelude::*; let value = create_signal(String::new()); view! { input(bind:value=value) } ``` -------------------------------- ### Interpolate children directly in Sycamore view! macro Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Demonstrates the ability to directly interpolate `children` within the Sycamore `view!` macro, simplifying the process of rendering child components or elements. ```rust view! { div { (children) } } ``` -------------------------------- ### Handle Click Events to Update State Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/adding-state.md Explains how to attach event listeners to DOM elements using the `on:*` directive within the `view!` macro. This example shows incrementing a signal's value on a button click. ```rust view! { button(on:click=move |_| counter.set(counter.get() + 1)) { "Increment" } p { "Count: " (counter) } } ``` -------------------------------- ### Component with Props (Struct-based) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Defines a component that accepts props via a struct, enabling dynamic content rendering based on passed data. Props are type-checked, ensuring data integrity. ```rust #[derive(Props)] struct HelloProps { name: String, } #[component] fn Hello(props: HelloProps) -> View { view! { p { "Hello, " (props.name) "!" } } } // Usage: // view! { // Hello(name="Sycamore".into()) // } ``` -------------------------------- ### Initialize State from Local Storage Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/todo-app.md Shows how to initialize the application's todo state by attempting to retrieve and deserialize data from the browser's local storage. If no data is found, it defaults to an empty list. ```rust // Initialize application state from localStorage. let local_storage = window() .local_storage() .unwrap() .expect("user has not enabled localStorage"); let todos: Signal> = if let Ok(Some(app_state)) = local_storage.get_item("todos") { serde_json::from_str(&app_state).unwrap_or_default() } else { Default::default() }; ``` -------------------------------- ### Sycamore list prop accepts static Vecs Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Shows how the `list` prop for `Indexed`/`Keyed` components in Sycamore now directly accepts static `Vec`s, eliminating the need for dummy signals when passing collections. ```rust // Old view! { Indexed( list=*create_signal(vec![...]), view=..., ) } // New view! { Indexed( list=vec![...], view=..., ) } ``` -------------------------------- ### Component with Children Prop Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Shows how to use the special 'children' prop to allow nesting of other views or components within a component. This enables creating wrapper components. ```rust #[derive(Props)] struct WrapperProps { children: Children, } #[component] fn Wrapper(props: WrapperProps) -> View { view! { div { (props.children) } } } // Usage: // view! { // Wrapper { // p { "Nested children" } // } // } ``` -------------------------------- ### Create Isomorphic Resource Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/resources-and-suspense.md Demonstrates creating an isomorphic resource using `create_isomorphic_resource`. This function is suitable for fetching data that needs to run on both the client and server. It wraps a `Signal>` which is initially `None`. ```rust use sycamore::prelude::*; use sycamore::web::create_isomorphic_resource; struct Data { // Define the data format here. } async fn fetch_data() -> Data { // Perform, for instance, an HTTP request to an API endpoint. } let resource = create_isomorphic_resource(fetch_data); ``` -------------------------------- ### `#[component]` Macro Syntax Update (Rust) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-7-to-0-8.md Demonstrates the change in the `#[component]` macro syntax from v0.7 to v0.8. The component name is now derived from the function name, making `PascalCase` idiomatic for component functions. ```rust // Old v0.7 syntax. #[component(MyComponent)] fn my_component(props: MyProps) -> View { ... } // New v0.8 syntax. #[component] fn MyComponent(props: MyProps) -> View { ... } ``` -------------------------------- ### Create and Use Sycamore Signals in Rust Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/adding-state.md Demonstrates how to create a Sycamore signal using `create_signal` and how to read its value with `get()` or `set()` it. Signals are reactive wrappers for state that track access and updates, allowing for efficient re-renders. ```rust let signal = create_signal(123); // Should print `123`. console_log!("{}", signal.get()); // Update the signal with a new value. signal.set(456); // Should print `456`. console_log!("{}", signal.get()); // `Signal` also implements `Display` so this is the same as the above. console_log!("{signal}"); ``` -------------------------------- ### Create Basic Elements Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/view-builder.md Demonstrates creating basic HTML elements like `a`, `button`, and `div` using their corresponding builder functions. These functions return specific element types that can be converted into `View`s. ```rust a() button() div() // etc... ``` -------------------------------- ### Sycamore Tweened Signal Animation Example Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/tweened.md Interpolates a float value from 0.0 to 100.0 over 250 milliseconds using Sycamore's `create_tweened_signal`. It utilizes a quadratic easing function for smooth animation. The `set` method triggers the animation. ```rust use std::time::Duration; use sycamore::easing; use sycamore::motion::create_tweened_signal; let tweened = create_tweened_signal(0.0f32, Duration::from_millis(250), easing::quad_out); tweened.set(100.0); ``` -------------------------------- ### Basic Body Styling with CSS Source: https://github.com/sycamore-rs/sycamore/blob/main/examples/hello-builder/index.html This snippet demonstrates basic CSS styling for the HTML body element. It sets the font family for the Sycamore application, ensuring a consistent look and feel across different browsers. ```css body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } ``` -------------------------------- ### Add Sycamore Dependency Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Adds the Sycamore library as a dependency to your Rust project using Cargo. This can be done via the command line or by manually editing `Cargo.toml`. ```bash cargo add sycamore@0.9.1 ``` ```toml sycamore = "0.9.1" ``` -------------------------------- ### Trunk WASM Optimization Link Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/cookbook/optimize-wasm-size.md Add this line to your `index.html` file when using Trunk to enable the `wasm-opt` tool, which performs further optimizations on the generated WASM binary. ```html ``` -------------------------------- ### Sycamore: Asynchronous Data Loading with Resources Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/posts/announcing-v0-9-0.md Illustrates the Sycamore Resources API for loading asynchronous data, showing how to create a resource that depends on reactive signals and integrates with Suspense for handling loading states and displaying data. ```rust let id = create_signal(...); let resource = create_resource(on(id, move || async move { fetch_user(id.get()).await })); view! { Suspense(fallback=move || view! { "Loading..." }) { (if let Some(data) = resource.get_clone() { view! { // Render data here } } else { // This branch is typically not reached if Suspense is used correctly view! {} }) } } ``` -------------------------------- ### Create Empty View with Default Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/view-dsl.md Shows an alternative method to create an empty view using the `View::default()` constructor, providing an equivalent to the `view! {}` macro. ```rust View::default() ``` -------------------------------- ### Migrate RcSignal to Signal in Sycamore Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md Sycamore v0.9 consolidates `RcSignal` into the standard `Signal` type, which is now `'static`. This change simplifies state management by removing the need for explicit reference counting. The migration involves replacing `RcSignal` with `Signal` and `create_rc_signal` with `create_signal`. ```rust /* Migration patterns for RcSignal: Match | Replacement -------------------|--------------- RcSignal | Signal create_rc_signal | create_signal */ ``` -------------------------------- ### Reactivity v2: Effect with Scoped Signals (Pre-v3) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/posts/announcing-v0-9-0.md Illustrates the older Reactivity v2 syntax requiring the 'cx' parameter for creating signals and effects. This highlights the complexity that Reactivity v3 aims to eliminate. ```rust let signal = create_signal(cx, 123); create_effect_scoped(cx, |cx| { let nested = create_signal(cx, 456); println!("{signal}, {nested}"); }); ``` -------------------------------- ### Access Signal Value Directly (Nightly Feature) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md When using the `nightly` feature in Sycamore, signals can be accessed directly by calling them like functions, providing a more concise syntax compared to the stable `.get()` method. This feature is experimental and requires a nightly Rust toolchain. ```rust // Stable let value = signal.get(); // Nightly only let value = signal(); ``` -------------------------------- ### Create Empty View Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/guide/view-dsl.md Demonstrates the simplest form of the `view!` macro, which creates an empty view. This is the most basic UI element that can be rendered. ```rust view! {} ``` -------------------------------- ### Sycamore Counter Component Example (Rust) Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/posts/announcing-v0-9-0.md This snippet demonstrates a basic Sycamore component in Rust. It creates a reactive counter that increments when a button is clicked. It utilizes Sycamore's `#[component]` macro for defining components, `create_signal` for reactive state management, and the `view!` macro for declarative UI construction. ```rust #[component] fn Counter(initial: i32) -> View { let mut value = create_signal(initial); view! { button(on:click=move |_| value += 1) { "Count: " (value) } } } ``` -------------------------------- ### Remove Scope and Lifetimes in Sycamore Reactivity Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/migration/0-8-to-0-9.md This section details the removal of explicit `cx: Scope` and lifetime annotations in Sycamore's reactivity system v3. It outlines common find-and-replace patterns to update existing code, simplifying component definitions and removing the need to manage lifetimes. ```rust /* Migration patterns for removing Scope and Lifetimes: Match | Replacement -----------------|------------ cx: Scope, | cx: Scope | cx, | cx | <'a, <'a> | &'a Signal | Signal &'a ReadSignal | ReadSignal */ ``` -------------------------------- ### Component with Inline Props Source: https://github.com/sycamore-rs/sycamore/blob/main/docs/next/introduction/your-first-app.md Demonstrates using the #[component(inline_props)] attribute to define component props directly as function parameters, reducing boilerplate code compared to struct-based props. ```rust #[component(inline_props)] fn Wrapper(children: Children) -> View { view! { div { (children) } } } ```