94 lines
4.7 KiB
Rust
94 lines
4.7 KiB
Rust
// The dioxus prelude contains a ton of common items used in dioxus apps. It's a good idea to import wherever you
|
|
// need dioxus
|
|
use dioxus::prelude::*;
|
|
|
|
use views::{Blog, Experiences, Home, Navbar, Projects, Skills};
|
|
|
|
/// Define a components module that contains all shared components for our app.
|
|
mod components;
|
|
/// Define a views module that contains the UI for all Layouts and Routes for our app.
|
|
mod views;
|
|
|
|
/// The Route enum is used to define the structure of internal routes in our app. All route enums need to derive
|
|
/// the [`Routable`] trait, which provides the necessary methods for the router to work.
|
|
///
|
|
/// Each variant represents a different URL pattern that can be matched by the router. If that pattern is matched,
|
|
/// the components for that route will be rendered.
|
|
#[derive(Debug, Clone, Routable, PartialEq)]
|
|
#[rustfmt::skip]
|
|
enum Route {
|
|
// The layout attribute defines a wrapper for all routes under the layout. Layouts are great for wrapping
|
|
// many routes with a common UI like a navbar.
|
|
#[layout(Navbar)]
|
|
// The route attribute defines the URL pattern that a specific route matches. If that pattern matches the URL,
|
|
// the component for that route will be rendered. The component name that is rendered defaults to the variant name.
|
|
#[route("/")]
|
|
Home {},
|
|
|
|
#[route("/skills")]
|
|
Skills {},
|
|
|
|
#[route("/projects")]
|
|
Projects {},
|
|
|
|
#[route("/experiences")]
|
|
Experiences {},
|
|
// The route attribute can include dynamic parameters that implement [`std::str::FromStr`] and [`std::fmt::Display`] with the `:` syntax.
|
|
// In this case, id will match any integer like `/blog/123` or `/blog/-456`.
|
|
#[route("/blog/:id")]
|
|
// Fields of the route variant will be passed to the component as props. In this case, the blog component must accept
|
|
// an `id` prop of type `i32`.
|
|
Blog { id: i32 },
|
|
}
|
|
|
|
// We can import assets in dioxus with the `asset!` macro. This macro takes a path to an asset relative to the crate root.
|
|
// The macro returns an `Asset` type that will display as the path to the asset in the browser or a local path in desktop bundles.
|
|
const FAVICON: Asset = asset!("/assets/favicon/favicon.ico");
|
|
const FAVICON_16: Asset = asset!("/assets/favicon/favicon-16x16.png");
|
|
const FAVICON_32: Asset = asset!("/assets/favicon/favicon-32x32.png");
|
|
const FAVICON_APPLE: Asset = asset!("/assets/favicon/apple-touch-icon.png");
|
|
const FAVICON_MANIFEST: Asset = asset!("/assets/favicon/site.webmanifest");
|
|
// The asset macro also minifies some assets like CSS and JS to make bundled smaller
|
|
const TAILWIND_CSS: Asset = asset!("/assets/styling/tailwind.css");
|
|
// const MEDIA_CSS: Asset = asset!("/assets/styling/media.css");
|
|
const MAIN_CSS: Asset = asset!("/assets/styling/main.css");
|
|
const ICONS_CSS: Asset = asset!("/assets/styling/icons.css");
|
|
|
|
fn main() {
|
|
// The `launch` function is the main entry point for a dioxus app. It takes a component and renders it with the platform feature
|
|
// you have enabled
|
|
dioxus::launch(App);
|
|
}
|
|
|
|
/// App is the main component of our app. Components are the building blocks of dioxus apps. Each component is a function
|
|
/// that takes some props and returns an Element. In this case, App takes no props because it is the root of our app.
|
|
///
|
|
/// Components should be annotated with `#[component]` to support props, better error messages, and autocomplete
|
|
#[component]
|
|
fn App() -> Element {
|
|
// The `rsx!` macro lets us define HTML inside of rust. It expands to an Element with all of our HTML inside.
|
|
let is_dark_theme = false;
|
|
rsx! {
|
|
// In addition to element and text (which we will see later), rsx can contain other components. In this case,
|
|
// we are using the `document::Link` component to add a link to our favicon and main CSS file into the head of our app.
|
|
document::Link { rel: "apple-touch-icon", sizes: "180x180", href:FAVICON_APPLE}
|
|
document::Link { rel: "icon", href: FAVICON }
|
|
document::Link { rel: "icon", href: FAVICON_16, sizes:"16x16" }
|
|
document::Link { rel: "icon", href: FAVICON_32, sizes:"32x32" }
|
|
document::Link { rel: "icon", href: FAVICON_MANIFEST}
|
|
|
|
document::Stylesheet { rel: "stylesheet", href: TAILWIND_CSS }
|
|
// document::Link { rel: "stylesheet", href: MEDIA_CSS }
|
|
document::Stylesheet { rel: "stylesheet", href: MAIN_CSS }
|
|
document::Stylesheet { rel: "stylesheet", href: ICONS_CSS }
|
|
|
|
// The router component renders the route enum we defined above. It will handle synchronization of the URL and render
|
|
// the layouts and components for the active route.
|
|
div {
|
|
class: "body",
|
|
"data-Theme": if is_dark_theme { "dark" } else { "light" },
|
|
Router::<Route> {}
|
|
}
|
|
}
|
|
}
|