Trading card city builder game?

convert to simpler setup, workspace mode was too convoluted

+307 -748
+7 -39
Cargo.lock
··· 39 39 checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" 40 40 41 41 [[package]] 42 - name = "api" 43 - version = "0.1.0" 44 - dependencies = [ 45 - "dioxus", 46 - ] 47 - 48 - [[package]] 49 42 name = "askama_escape" 50 43 version = "0.13.0" 51 44 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 321 314 "glib-sys", 322 315 "libc", 323 316 "system-deps", 317 + ] 318 + 319 + [[package]] 320 + name = "cartography" 321 + version = "0.1.0" 322 + dependencies = [ 323 + "dioxus", 324 324 ] 325 325 326 326 [[package]] ··· 814 814 "rustc_version", 815 815 "syn 2.0.114", 816 816 "unicode-xid", 817 - ] 818 - 819 - [[package]] 820 - name = "desktop" 821 - version = "0.1.0" 822 - dependencies = [ 823 - "dioxus", 824 - "ui", 825 817 ] 826 818 827 819 [[package]] ··· 3020 3012 ] 3021 3013 3022 3014 [[package]] 3023 - name = "mobile" 3024 - version = "0.1.0" 3025 - dependencies = [ 3026 - "dioxus", 3027 - "ui", 3028 - ] 3029 - 3030 - [[package]] 3031 3015 name = "muda" 3032 3016 version = "0.17.1" 3033 3017 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5131 5115 checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" 5132 5116 5133 5117 [[package]] 5134 - name = "ui" 5135 - version = "0.1.0" 5136 - dependencies = [ 5137 - "api", 5138 - "dioxus", 5139 - ] 5140 - 5141 - [[package]] 5142 5118 name = "unicase" 5143 5119 version = "2.9.0" 5144 5120 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5352 5328 "wasm-bindgen", 5353 5329 "wasm-bindgen-futures", 5354 5330 "web-sys", 5355 - ] 5356 - 5357 - [[package]] 5358 - name = "web" 5359 - version = "0.1.0" 5360 - dependencies = [ 5361 - "dioxus", 5362 - "ui", 5363 5331 ] 5364 5332 5365 5333 [[package]]
+15 -14
Cargo.toml
··· 1 - [workspace] 2 - resolver = "2" 3 - members = [ 4 - "packages/ui", 5 - "packages/web", 6 - "packages/desktop", 7 - "packages/mobile", 8 - "packages/api", 9 - ] 1 + [package] 2 + name = "cartography" 3 + version = "0.1.0" 4 + authors = ["Cameron Eldridge <cameldridge@gmail.com>"] 5 + edition = "2021" 6 + 7 + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 8 11 - [workspace.dependencies] 12 - dioxus = { version = "0.7.3" } 9 + [dependencies] 10 + dioxus = { version = "0.7.1", features = ["router", "fullstack"] } 13 11 14 - # workspace 15 - ui = { path = "packages/ui" } 16 - api = { path = "packages/api" } 12 + [features] 13 + default = ["web"] 14 + web = ["dioxus/web"] 15 + desktop = ["dioxus/desktop"] 16 + mobile = ["dioxus/mobile"] 17 + server = ["dioxus/server"]
+21
Dioxus.toml
··· 1 + [application] 2 + 3 + [web.app] 4 + 5 + # HTML title tag content 6 + title = "Cartography" 7 + 8 + # include `assets` in web platform 9 + [web.resource] 10 + 11 + # Additional CSS style files 12 + style = [] 13 + 14 + # Additional JavaScript files 15 + script = [] 16 + 17 + [web.resource.dev] 18 + 19 + # Javascript code file 20 + # serve: [dev-server] only 21 + script = []
+24 -2
README.md
··· 1 - # Cartography? 1 + # Development 2 + 3 + Your new bare-bones project includes minimal organization with a single `main.rs` file and a few assets. 4 + 5 + ``` 6 + project/ 7 + ├─ assets/ # Any assets that are used by the app should be placed here 8 + ├─ src/ 9 + │ ├─ main.rs # main.rs is the entry point to your application and currently contains all components for the app 10 + ├─ Cargo.toml # The Cargo.toml file defines the dependencies and feature flags for your project 11 + ``` 2 12 3 - A trading card city builder game? Or something. 13 + ### Serving Your App 14 + 15 + Run the following command in the root of your project to start developing with the default platform: 16 + 17 + ```bash 18 + dx serve --platform web 19 + ``` 20 + 21 + To run for a different platform, use the `--platform platform` flag. E.g. 22 + ```bash 23 + dx serve --platform desktop 24 + ``` 25 +
+107
assets/main.css
··· 1 + /* App-wide styling */ 2 + body { 3 + background-color: #0f1116; 4 + color: #ffffff; 5 + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 6 + margin: 20px; 7 + } 8 + 9 + #hero { 10 + margin: 0; 11 + display: flex; 12 + flex-direction: column; 13 + justify-content: center; 14 + align-items: center; 15 + } 16 + 17 + #links { 18 + width: 400px; 19 + text-align: left; 20 + font-size: x-large; 21 + color: white; 22 + display: flex; 23 + flex-direction: column; 24 + } 25 + 26 + #links a { 27 + color: white; 28 + text-decoration: none; 29 + margin-top: 20px; 30 + margin: 10px 0px; 31 + border: white 1px solid; 32 + border-radius: 5px; 33 + padding: 10px; 34 + } 35 + 36 + #links a:hover { 37 + background-color: #1f1f1f; 38 + cursor: pointer; 39 + } 40 + 41 + #header { 42 + max-width: 1200px; 43 + } 44 + 45 + /* Navbar */ 46 + #navbar { 47 + display: flex; 48 + flex-direction: row; 49 + } 50 + 51 + #navbar a { 52 + color: #ffffff; 53 + margin-right: 20px; 54 + text-decoration: none; 55 + transition: color 0.2s ease; 56 + } 57 + 58 + #navbar a:hover { 59 + cursor: pointer; 60 + color: #91a4d2; 61 + } 62 + 63 + /* Blog page */ 64 + #blog { 65 + margin-top: 50px; 66 + } 67 + 68 + #blog a { 69 + color: #ffffff; 70 + margin-top: 50px; 71 + } 72 + 73 + /* Echo */ 74 + #echo { 75 + width: 360px; 76 + margin-left: auto; 77 + margin-right: auto; 78 + margin-top: 50px; 79 + background-color: #1e222d; 80 + padding: 20px; 81 + border-radius: 10px; 82 + } 83 + 84 + #echo>h4 { 85 + margin: 0px 0px 15px 0px; 86 + } 87 + 88 + 89 + #echo>input { 90 + border: none; 91 + border-bottom: 1px white solid; 92 + background-color: transparent; 93 + color: #ffffff; 94 + transition: border-bottom-color 0.2s ease; 95 + outline: none; 96 + display: block; 97 + padding: 0px 0px 5px 0px; 98 + width: 100%; 99 + } 100 + 101 + #echo>input:focus { 102 + border-bottom-color: #6d85c6; 103 + } 104 + 105 + #echo>p { 106 + margin: 20px 0px 0px auto; 107 + }
-10
packages/api/Cargo.toml
··· 1 - [package] 2 - name = "api" 3 - version = "0.1.0" 4 - edition = "2021" 5 - 6 - [dependencies] 7 - dioxus = { workspace = true, features = ["fullstack"] } 8 - 9 - [features] 10 - server = ["dioxus/server"]
-13
packages/api/README.md
··· 1 - # API 2 - 3 - This crate contains all shared fullstack server functions. This is a great place to place any server-only logic you would like to expose in multiple platforms like a method that accesses your database or a method that sends an email. 4 - 5 - This crate will be built twice: 6 - 1. Once for the server build with the `dioxus/server` feature enabled 7 - 2. Once for the client build with the client feature disabled 8 - 9 - During the server build, the server functions will be collected and hosted on a public API for the client to call. During the client build, the server functions will be compiled into the client build. 10 - 11 - ## Dependencies 12 - 13 - Most server dependencies (like sqlx and tokio) will not compile on client platforms like WASM. To avoid building server dependencies on the client, you should add platform specific dependencies under the `server` feature in the [Cargo.toml](../Cargo.toml) file. More details about managing server only dependencies can be found in the [Dioxus guide](https://dioxuslabs.com/learn/0.7/guides/fullstack/managing_dependencies#adding-server-only-dependencies).
-8
packages/api/src/lib.rs
··· 1 - //! This crate contains all shared fullstack server functions. 2 - use dioxus::prelude::*; 3 - 4 - /// Echo the user input on the server. 5 - #[post("/api/echo")] 6 - pub async fn echo(input: String) -> Result<String, ServerFnError> { 7 - Ok(input) 8 - }
-13
packages/desktop/Cargo.toml
··· 1 - [package] 2 - name = "desktop" 3 - version = "0.1.0" 4 - edition = "2021" 5 - 6 - [dependencies] 7 - dioxus = { workspace = true, features = ["router", "fullstack"] } 8 - ui = { workspace = true } 9 - 10 - [features] 11 - default = [] 12 - desktop = ["dioxus/desktop"] 13 - server = ["dioxus/server", "ui/server"]
-30
packages/desktop/README.md
··· 1 - # Development 2 - 3 - The desktop crate defines the entrypoint for the desktop app along with any assets, components and dependencies that are specific to desktop builds. The desktop crate starts out something like this: 4 - 5 - ``` 6 - desktop/ 7 - ├─ assets/ # Assets used by the desktop app - Any platform specific assets should go in this folder 8 - ├─ src/ 9 - │ ├─ main.rs # The entrypoint for the desktop app.It also defines the routes for the desktop platform 10 - │ ├─ views/ # The views each route will render in the desktop version of the app 11 - │ │ ├─ mod.rs # Defines the module for the views route and re-exports the components for each route 12 - │ │ ├─ blog.rs # The component that will render at the /blog/:id route 13 - │ │ ├─ home.rs # The component that will render at the / route 14 - ├─ Cargo.toml # The desktop crate's Cargo.toml - This should include all desktop specific dependencies 15 - ``` 16 - 17 - ## Dependencies 18 - Since you have fullstack enabled, the desktop crate will be built two times: 19 - 1. Once for the server build with the `server` feature enabled 20 - 2. Once for the client build with the `desktop` feature enabled 21 - 22 - You should make all desktop specific dependencies optional and only enabled in the `desktop` feature. This will ensure that the server builds don't pull in desktop specific dependencies which cuts down on build times significantly. 23 - 24 - ### Serving Your Desktop App 25 - 26 - You can start your desktop app with the following command: 27 - 28 - ```bash 29 - dx serve 30 - ```
-8
packages/desktop/assets/blog.css
··· 1 - #blog { 2 - margin-top: 50px; 3 - } 4 - 5 - #blog a { 6 - color: #ffffff; 7 - margin-top: 50px; 8 - }
-6
packages/desktop/assets/main.css
··· 1 - body { 2 - background-color: #0f1116; 3 - color: #ffffff; 4 - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 5 - margin: 20px; 6 - }
-54
packages/desktop/src/main.rs
··· 1 - use dioxus::prelude::*; 2 - 3 - use ui::Navbar; 4 - use views::{Blog, Home}; 5 - 6 - mod views; 7 - 8 - #[derive(Debug, Clone, Routable, PartialEq)] 9 - #[rustfmt::skip] 10 - enum Route { 11 - #[layout(DesktopNavbar)] 12 - #[route("/")] 13 - Home {}, 14 - #[route("/blog/:id")] 15 - Blog { id: i32 }, 16 - } 17 - 18 - const MAIN_CSS: Asset = asset!("/assets/main.css"); 19 - 20 - fn main() { 21 - dioxus::launch(App); 22 - } 23 - 24 - #[component] 25 - fn App() -> Element { 26 - // Build cool things ✌️ 27 - 28 - rsx! { 29 - // Global app resources 30 - document::Link { rel: "stylesheet", href: MAIN_CSS } 31 - 32 - Router::<Route> {} 33 - } 34 - } 35 - 36 - /// A desktop-specific Router around the shared `Navbar` component 37 - /// which allows us to use the desktop-specific `Route` enum. 38 - #[component] 39 - fn DesktopNavbar() -> Element { 40 - rsx! { 41 - Navbar { 42 - Link { 43 - to: Route::Home {}, 44 - "Home" 45 - } 46 - Link { 47 - to: Route::Blog { id: 1 }, 48 - "Blog" 49 - } 50 - } 51 - 52 - Outlet::<Route> {} 53 - } 54 - }
-30
packages/desktop/src/views/blog.rs
··· 1 - use crate::Route; 2 - use dioxus::prelude::*; 3 - 4 - const BLOG_CSS: Asset = asset!("/assets/blog.css"); 5 - 6 - #[component] 7 - pub fn Blog(id: i32) -> Element { 8 - rsx! { 9 - document::Link { rel: "stylesheet", href: BLOG_CSS} 10 - 11 - div { 12 - id: "blog", 13 - 14 - // Content 15 - h1 { "This is blog #{id}!" } 16 - p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." } 17 - 18 - // Navigation links 19 - Link { 20 - to: Route::Blog { id: id - 1 }, 21 - "Previous" 22 - } 23 - span { " <---> " } 24 - Link { 25 - to: Route::Blog { id: id + 1 }, 26 - "Next" 27 - } 28 - } 29 - } 30 - }
-10
packages/desktop/src/views/home.rs
··· 1 - use dioxus::prelude::*; 2 - use ui::{Echo, Hero}; 3 - 4 - #[component] 5 - pub fn Home() -> Element { 6 - rsx! { 7 - Hero {} 8 - Echo {} 9 - } 10 - }
-5
packages/desktop/src/views/mod.rs
··· 1 - mod home; 2 - pub use home::Home; 3 - 4 - mod blog; 5 - pub use blog::Blog;
-13
packages/mobile/Cargo.toml
··· 1 - [package] 2 - name = "mobile" 3 - version = "0.1.0" 4 - edition = "2021" 5 - 6 - [dependencies] 7 - dioxus = { workspace = true, features = ["router", "fullstack"] } 8 - ui = { workspace = true } 9 - 10 - [features] 11 - default = [] 12 - mobile = ["dioxus/mobile"] 13 - server = ["dioxus/server", "ui/server"]
-30
packages/mobile/README.md
··· 1 - # Development 2 - 3 - The mobile crate defines the entrypoint for the mobile app along with any assets, components and dependencies that are specific to mobile builds. The mobile crate starts out something like this: 4 - 5 - ``` 6 - mobile/ 7 - ├─ assets/ # Assets used by the mobile app - Any platform specific assets should go in this folder 8 - ├─ src/ 9 - │ ├─ main.rs # The entrypoint for the mobile app.It also defines the routes for the mobile platform 10 - │ ├─ views/ # The views each route will render in the mobile version of the app 11 - │ │ ├─ mod.rs # Defines the module for the views route and re-exports the components for each route 12 - │ │ ├─ blog.rs # The component that will render at the /blog/:id route 13 - │ │ ├─ home.rs # The component that will render at the / route 14 - ├─ Cargo.toml # The mobile crate's Cargo.toml - This should include all mobile specific dependencies 15 - ``` 16 - 17 - ## Dependencies 18 - Since you have fullstack enabled, the mobile crate will be built two times: 19 - 1. Once for the server build with the `server` feature enabled 20 - 2. Once for the client build with the `mobile` feature enabled 21 - 22 - You should make all mobile specific dependencies optional and only enabled in the `mobile` feature. This will ensure that the server builds don't pull in mobile specific dependencies which cuts down on build times significantly. 23 - 24 - ### Serving Your Mobile App 25 - 26 - Mobile platforms are shared in a single crate. To serve mobile, you need to explicitly set your target device to `android` or `ios`: 27 - 28 - ```bash 29 - dx serve --platform android 30 - ```
-8
packages/mobile/assets/blog.css
··· 1 - #blog { 2 - margin-top: 50px; 3 - } 4 - 5 - #blog a { 6 - color: #ffffff; 7 - margin-top: 50px; 8 - }
-6
packages/mobile/assets/main.css
··· 1 - body { 2 - background-color: #0f1116; 3 - color: #ffffff; 4 - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 5 - margin: 20px; 6 - }
-54
packages/mobile/src/main.rs
··· 1 - use dioxus::prelude::*; 2 - 3 - use ui::Navbar; 4 - use views::{Blog, Home}; 5 - 6 - mod views; 7 - 8 - #[derive(Debug, Clone, Routable, PartialEq)] 9 - #[rustfmt::skip] 10 - enum Route { 11 - #[layout(MobileNavbar)] 12 - #[route("/")] 13 - Home {}, 14 - #[route("/blog/:id")] 15 - Blog { id: i32 }, 16 - } 17 - 18 - const MAIN_CSS: Asset = asset!("/assets/main.css"); 19 - 20 - fn main() { 21 - dioxus::launch(App); 22 - } 23 - 24 - #[component] 25 - fn App() -> Element { 26 - // Build cool things ✌️ 27 - 28 - rsx! { 29 - // Global app resources 30 - document::Link { rel: "stylesheet", href: MAIN_CSS } 31 - 32 - Router::<Route> {} 33 - } 34 - } 35 - 36 - /// A mobile-specific Router around the shared `Navbar` component 37 - /// which allows us to use the mobile-specific `Route` enum. 38 - #[component] 39 - fn MobileNavbar() -> Element { 40 - rsx! { 41 - Navbar { 42 - Link { 43 - to: Route::Home {}, 44 - "Home" 45 - } 46 - Link { 47 - to: Route::Blog { id: 1 }, 48 - "Blog" 49 - } 50 - } 51 - 52 - Outlet::<Route> {} 53 - } 54 - }
-30
packages/mobile/src/views/blog.rs
··· 1 - use crate::Route; 2 - use dioxus::prelude::*; 3 - 4 - const BLOG_CSS: Asset = asset!("/assets/blog.css"); 5 - 6 - #[component] 7 - pub fn Blog(id: i32) -> Element { 8 - rsx! { 9 - document::Link { rel: "stylesheet", href: BLOG_CSS} 10 - 11 - div { 12 - id: "blog", 13 - 14 - // Content 15 - h1 { "This is blog #{id}!" } 16 - p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." } 17 - 18 - // Navigation links 19 - Link { 20 - to: Route::Blog { id: id - 1 }, 21 - "Previous" 22 - } 23 - span { " <---> " } 24 - Link { 25 - to: Route::Blog { id: id + 1 }, 26 - "Next" 27 - } 28 - } 29 - } 30 - }
-10
packages/mobile/src/views/home.rs
··· 1 - use dioxus::prelude::*; 2 - use ui::{Echo, Hero}; 3 - 4 - #[component] 5 - pub fn Home() -> Element { 6 - rsx! { 7 - Hero {} 8 - Echo {} 9 - } 10 - }
-5
packages/mobile/src/views/mod.rs
··· 1 - mod home; 2 - pub use home::Home; 3 - 4 - mod blog; 5 - pub use blog::Blog;
-11
packages/ui/Cargo.toml
··· 1 - [package] 2 - name = "ui" 3 - version = "0.1.0" 4 - edition = "2021" 5 - 6 - [dependencies] 7 - dioxus = { workspace = true } 8 - api = { workspace = true } 9 - 10 - [features] 11 - server = ["api/server"]
-16
packages/ui/README.md
··· 1 - # UI 2 - 3 - This crate contains all shared components for the workspace. This is a great place to place any UI you would like to use in multiple platforms like a common `Button` or `Navbar` component. 4 - 5 - ``` 6 - ui/ 7 - ├─ src/ 8 - │ ├─ lib.rs # The entrypoint for the ui crate 9 - │ ├─ hero.rs # The Hero component that will be used in every platform 10 - │ ├─ echo.rs # The shared echo component that communicates with the server 11 - │ ├─ navbar.rs # The Navbar component that will be used in the layout of every platform's router 12 - ``` 13 - 14 - ## Dependencies 15 - 16 - Since this crate is shared between multiple platforms, it should not pull in any platform specific dependencies. For example, if you want to use the `web_sys` crate in the web build of your app, you should not add it to this crate. Instead, you should add platform specific dependencies to the [web](../web/Cargo.toml), [desktop](../desktop/Cargo.toml), or [mobile](../mobile/Cargo.toml) crates.
packages/ui/assets/header.svg assets/header.svg
-34
packages/ui/assets/styling/echo.css
··· 1 - #echo { 2 - width: 360px; 3 - margin-left: auto; 4 - margin-right: auto; 5 - margin-top: 50px; 6 - background-color: #1e222d; 7 - padding: 20px; 8 - border-radius: 10px; 9 - } 10 - 11 - #echo>h4 { 12 - margin: 0px 0px 15px 0px; 13 - } 14 - 15 - 16 - #echo>input { 17 - border: none; 18 - border-bottom: 1px white solid; 19 - background-color: transparent; 20 - color: #ffffff; 21 - transition: border-bottom-color 0.2s ease; 22 - outline: none; 23 - display: block; 24 - padding: 0px 0px 5px 0px; 25 - width: 100%; 26 - } 27 - 28 - #echo>input:focus { 29 - border-bottom-color: #6d85c6; 30 - } 31 - 32 - #echo>p { 33 - margin: 20px 0px 0px auto; 34 - }
-35
packages/ui/assets/styling/hero.css
··· 1 - #hero { 2 - margin: 0; 3 - display: flex; 4 - flex-direction: column; 5 - justify-content: center; 6 - align-items: center; 7 - } 8 - 9 - #links { 10 - width: 400px; 11 - text-align: left; 12 - font-size: x-large; 13 - color: white; 14 - display: flex; 15 - flex-direction: column; 16 - } 17 - 18 - #links a { 19 - color: white; 20 - text-decoration: none; 21 - margin-top: 20px; 22 - margin: 10px 0px; 23 - border: white 1px solid; 24 - border-radius: 5px; 25 - padding: 10px; 26 - } 27 - 28 - #links a:hover { 29 - background-color: #1f1f1f; 30 - cursor: pointer; 31 - } 32 - 33 - #header { 34 - max-width: 1200px; 35 - }
-16
packages/ui/assets/styling/navbar.css
··· 1 - #navbar { 2 - display: flex; 3 - flex-direction: row; 4 - } 5 - 6 - #navbar a { 7 - color: #ffffff; 8 - margin-right: 20px; 9 - text-decoration: none; 10 - transition: color 0.2s ease; 11 - } 12 - 13 - #navbar a:hover { 14 - cursor: pointer; 15 - color: #91a4d2; 16 - }
-31
packages/ui/src/echo.rs
··· 1 - use dioxus::prelude::*; 2 - 3 - const ECHO_CSS: Asset = asset!("/assets/styling/echo.css"); 4 - 5 - /// Echo component that demonstrates fullstack server functions. 6 - #[component] 7 - pub fn Echo() -> Element { 8 - let mut response = use_signal(|| String::new()); 9 - 10 - rsx! { 11 - document::Link { rel: "stylesheet", href: ECHO_CSS } 12 - div { 13 - id: "echo", 14 - h4 { "ServerFn Echo" } 15 - input { 16 - placeholder: "Type here to echo...", 17 - oninput: move |event| async move { 18 - let data = api::echo(event.value()).await.unwrap(); 19 - response.set(data); 20 - }, 21 - } 22 - 23 - if !response().is_empty() { 24 - p { 25 - "Server echoed: " 26 - i { "{response}" } 27 - } 28 - } 29 - } 30 - } 31 - }
-24
packages/ui/src/hero.rs
··· 1 - use dioxus::prelude::*; 2 - 3 - const HERO_CSS: Asset = asset!("/assets/styling/hero.css"); 4 - const HEADER_SVG: Asset = asset!("/assets/header.svg"); 5 - 6 - #[component] 7 - pub fn Hero() -> Element { 8 - rsx! { 9 - document::Link { rel: "stylesheet", href: HERO_CSS } 10 - 11 - div { 12 - id: "hero", 13 - img { src: HEADER_SVG, id: "header" } 14 - div { id: "links", 15 - a { href: "https://dioxuslabs.com/learn/0.7/", "📚 Learn Dioxus" } 16 - a { href: "https://dioxuslabs.com/awesome", "🚀 Awesome Dioxus" } 17 - a { href: "https://github.com/dioxus-community/", "📡 Community Libraries" } 18 - a { href: "https://github.com/DioxusLabs/sdk", "⚙️ Dioxus Development Kit" } 19 - a { href: "https://marketplace.visualstudio.com/items?itemName=DioxusLabs.dioxus", "💫 VSCode Extension" } 20 - a { href: "https://discord.gg/XgGxMSkvUM", "👋 Community Discord" } 21 - } 22 - } 23 - } 24 - }
-10
packages/ui/src/lib.rs
··· 1 - //! This crate contains all shared UI for the workspace. 2 - 3 - mod hero; 4 - pub use hero::Hero; 5 - 6 - mod navbar; 7 - pub use navbar::Navbar; 8 - 9 - mod echo; 10 - pub use echo::Echo;
-15
packages/ui/src/navbar.rs
··· 1 - use dioxus::prelude::*; 2 - 3 - const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css"); 4 - 5 - #[component] 6 - pub fn Navbar(children: Element) -> Element { 7 - rsx! { 8 - document::Link { rel: "stylesheet", href: NAVBAR_CSS } 9 - 10 - div { 11 - id: "navbar", 12 - {children} 13 - } 14 - } 15 - }
-13
packages/web/Cargo.toml
··· 1 - [package] 2 - name = "web" 3 - version = "0.1.0" 4 - edition = "2021" 5 - 6 - [dependencies] 7 - dioxus = { workspace = true, features = ["router", "fullstack"] } 8 - ui = { workspace = true } 9 - 10 - [features] 11 - default = [] 12 - web = ["dioxus/web"] 13 - server = ["dioxus/server", "ui/server"]
-30
packages/web/README.md
··· 1 - # Development 2 - 3 - The web crate defines the entrypoint for the web app along with any assets, components and dependencies that are specific to web builds. The web crate starts out something like this: 4 - 5 - ``` 6 - web/ 7 - ├─ assets/ # Assets used by the web app - Any platform specific assets should go in this folder 8 - ├─ src/ 9 - │ ├─ main.rs # The entrypoint for the web app.It also defines the routes for the web platform 10 - │ ├─ views/ # The views each route will render in the web version of the app 11 - │ │ ├─ mod.rs # Defines the module for the views route and re-exports the components for each route 12 - │ │ ├─ blog.rs # The component that will render at the /blog/:id route 13 - │ │ ├─ home.rs # The component that will render at the / route 14 - ├─ Cargo.toml # The web crate's Cargo.toml - This should include all web specific dependencies 15 - ``` 16 - 17 - ## Dependencies 18 - Since you have fullstack enabled, the web crate will be built two times: 19 - 1. Once for the server build with the `server` feature enabled 20 - 2. Once for the client build with the `web` feature enabled 21 - 22 - You should make all web specific dependencies optional and only enabled in the `web` feature. This will ensure that the server builds don't pull in web specific dependencies which cuts down on build times significantly. 23 - 24 - ### Serving Your Web App 25 - 26 - You can start your web app with the following command: 27 - 28 - ```bash 29 - dx serve 30 - ```
-8
packages/web/assets/blog.css
··· 1 - #blog { 2 - margin-top: 50px; 3 - } 4 - 5 - #blog a { 6 - color: #ffffff; 7 - margin-top: 50px; 8 - }
packages/web/assets/favicon.ico assets/favicon.ico
-6
packages/web/assets/main.css
··· 1 - body { 2 - background-color: #0f1116; 3 - color: #ffffff; 4 - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 5 - margin: 20px; 6 - }
-56
packages/web/src/main.rs
··· 1 - use dioxus::prelude::*; 2 - 3 - use ui::Navbar; 4 - use views::{Blog, Home}; 5 - 6 - mod views; 7 - 8 - #[derive(Debug, Clone, Routable, PartialEq)] 9 - #[rustfmt::skip] 10 - enum Route { 11 - #[layout(WebNavbar)] 12 - #[route("/")] 13 - Home {}, 14 - #[route("/blog/:id")] 15 - Blog { id: i32 }, 16 - } 17 - 18 - const FAVICON: Asset = asset!("/assets/favicon.ico"); 19 - const MAIN_CSS: Asset = asset!("/assets/main.css"); 20 - 21 - fn main() { 22 - dioxus::launch(App); 23 - } 24 - 25 - #[component] 26 - fn App() -> Element { 27 - // Build cool things ✌️ 28 - 29 - rsx! { 30 - // Global app resources 31 - document::Link { rel: "icon", href: FAVICON } 32 - document::Link { rel: "stylesheet", href: MAIN_CSS } 33 - 34 - Router::<Route> {} 35 - } 36 - } 37 - 38 - /// A web-specific Router around the shared `Navbar` component 39 - /// which allows us to use the web-specific `Route` enum. 40 - #[component] 41 - fn WebNavbar() -> Element { 42 - rsx! { 43 - Navbar { 44 - Link { 45 - to: Route::Home {}, 46 - "Home" 47 - } 48 - Link { 49 - to: Route::Blog { id: 1 }, 50 - "Blog" 51 - } 52 - } 53 - 54 - Outlet::<Route> {} 55 - } 56 - }
-30
packages/web/src/views/blog.rs
··· 1 - use crate::Route; 2 - use dioxus::prelude::*; 3 - 4 - const BLOG_CSS: Asset = asset!("/assets/blog.css"); 5 - 6 - #[component] 7 - pub fn Blog(id: i32) -> Element { 8 - rsx! { 9 - document::Link { rel: "stylesheet", href: BLOG_CSS} 10 - 11 - div { 12 - id: "blog", 13 - 14 - // Content 15 - h1 { "This is blog #{id}!" } 16 - p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." } 17 - 18 - // Navigation links 19 - Link { 20 - to: Route::Blog { id: id - 1 }, 21 - "Previous" 22 - } 23 - span { " <---> " } 24 - Link { 25 - to: Route::Blog { id: id + 1 }, 26 - "Next" 27 - } 28 - } 29 - } 30 - }
-10
packages/web/src/views/home.rs
··· 1 - use dioxus::prelude::*; 2 - use ui::{Echo, Hero}; 3 - 4 - #[component] 5 - pub fn Home() -> Element { 6 - rsx! { 7 - Hero {} 8 - Echo {} 9 - } 10 - }
-5
packages/web/src/views/mod.rs
··· 1 - mod home; 2 - pub use home::Home; 3 - 4 - mod blog; 5 - pub use blog::Blog;
+133
src/main.rs
··· 1 + use dioxus::prelude::*; 2 + 3 + #[derive(Debug, Clone, Routable, PartialEq)] 4 + #[rustfmt::skip] 5 + enum Route { 6 + #[layout(Navbar)] 7 + #[route("/")] 8 + Home {}, 9 + #[route("/blog/:id")] 10 + Blog { id: i32 }, 11 + } 12 + 13 + const FAVICON: Asset = asset!("/assets/favicon.ico"); 14 + const MAIN_CSS: Asset = asset!("/assets/main.css"); 15 + const HEADER_SVG: Asset = asset!("/assets/header.svg"); 16 + 17 + fn main() { 18 + dioxus::launch(App); 19 + } 20 + 21 + #[component] 22 + fn App() -> Element { 23 + rsx! { 24 + document::Link { rel: "icon", href: FAVICON } 25 + document::Link { rel: "stylesheet", href: MAIN_CSS } 26 + Router::<Route> {} 27 + } 28 + } 29 + 30 + #[component] 31 + pub fn Hero() -> Element { 32 + rsx! { 33 + div { 34 + id: "hero", 35 + img { src: HEADER_SVG, id: "header" } 36 + div { id: "links", 37 + a { href: "https://dioxuslabs.com/learn/0.7/", "📚 Learn Dioxus" } 38 + a { href: "https://dioxuslabs.com/awesome", "🚀 Awesome Dioxus" } 39 + a { href: "https://github.com/dioxus-community/", "📡 Community Libraries" } 40 + a { href: "https://github.com/DioxusLabs/sdk", "⚙️ Dioxus Development Kit" } 41 + a { href: "https://marketplace.visualstudio.com/items?itemName=DioxusLabs.dioxus", "💫 VSCode Extension" } 42 + a { href: "https://discord.gg/XgGxMSkvUM", "👋 Community Discord" } 43 + } 44 + } 45 + } 46 + } 47 + 48 + /// Home page 49 + #[component] 50 + fn Home() -> Element { 51 + rsx! { 52 + Hero {} 53 + Echo {} 54 + } 55 + } 56 + 57 + /// Blog page 58 + #[component] 59 + pub fn Blog(id: i32) -> Element { 60 + rsx! { 61 + div { 62 + id: "blog", 63 + 64 + // Content 65 + h1 { "This is blog #{id}!" } 66 + p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." } 67 + 68 + // Navigation links 69 + Link { 70 + to: Route::Blog { id: id - 1 }, 71 + "Previous" 72 + } 73 + span { " <---> " } 74 + Link { 75 + to: Route::Blog { id: id + 1 }, 76 + "Next" 77 + } 78 + } 79 + } 80 + } 81 + 82 + /// Shared navbar component. 83 + #[component] 84 + fn Navbar() -> Element { 85 + rsx! { 86 + div { 87 + id: "navbar", 88 + Link { 89 + to: Route::Home {}, 90 + "Home" 91 + } 92 + Link { 93 + to: Route::Blog { id: 1 }, 94 + "Blog" 95 + } 96 + } 97 + 98 + Outlet::<Route> {} 99 + } 100 + } 101 + 102 + /// Echo component that demonstrates fullstack server functions. 103 + #[component] 104 + fn Echo() -> Element { 105 + let mut response = use_signal(|| String::new()); 106 + 107 + rsx! { 108 + div { 109 + id: "echo", 110 + h4 { "ServerFn Echo" } 111 + input { 112 + placeholder: "Type here to echo...", 113 + oninput: move |event| async move { 114 + let data = echo_server(event.value()).await.unwrap(); 115 + response.set(data); 116 + }, 117 + } 118 + 119 + if !response().is_empty() { 120 + p { 121 + "Server echoed: " 122 + i { "{response}" } 123 + } 124 + } 125 + } 126 + } 127 + } 128 + 129 + /// Echo the user input on the server. 130 + #[post("/api/echo")] 131 + async fn echo_server(input: String) -> Result<String, ServerFnError> { 132 + Ok(input) 133 + }