feat: added server and web base code

This commit is contained in:
Sharang Parnerkar
2026-02-15 23:37:25 +01:00
parent 1072770d11
commit 10aadfae41
17 changed files with 465 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
// AUTOGENERATED Components module
pub mod toast;

View File

@@ -0,0 +1,15 @@
use dioxus::prelude::*;
use dioxus_primitives::toast::{self, ToastProviderProps};
#[component]
pub fn ToastProvider(props: ToastProviderProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("./style.css") }
toast::ToastProvider {
default_duration: props.default_duration,
max_toasts: props.max_toasts,
render_toast: props.render_toast,
{props.children}
}
}
}

View File

@@ -0,0 +1,2 @@
mod component;
pub use component::*;

View File

@@ -0,0 +1,185 @@
.toast-container {
position: fixed;
z-index: 9999;
right: 20px;
bottom: 20px;
max-width: 350px;
}
.toast-list {
display: flex;
flex-direction: column-reverse;
padding: 0;
margin: 0;
gap: 0.75rem;
}
.toast-item {
display: flex;
}
.toast {
z-index: calc(var(--toast-count) - var(--toast-index));
display: flex;
overflow: hidden;
width: 18rem;
height: 4rem;
box-sizing: border-box;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border: 1px solid var(--light, var(--primary-color-6))
var(--dark, var(--primary-color-7));
border-radius: 0.5rem;
margin-top: -4rem;
box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
filter: var(--light, none)
var(
--dark,
brightness(calc(0.5 + 0.5 * (1 - ((var(--toast-index) + 1) / 4))))
);
opacity: calc(1 - var(--toast-hidden));
transform: scale(
calc(100% - var(--toast-index) * 5%),
calc(100% - var(--toast-index) * 2%)
);
transition: transform 0.2s ease, margin-top 0.2s ease, opacity 0.2s ease;
--toast-hidden: calc(min(max(0, var(--toast-index) - 2), 1));
}
.toast-container:not(:hover, :focus-within)
.toast[data-toast-even]:not([data-top]) {
animation: slide-up-even 0.2s ease-out;
}
.toast-container:not(:hover, :focus-within)
.toast[data-toast-odd]:not([data-top]) {
animation: slide-up-odd 0.2s ease-out;
}
@keyframes slide-up-even {
from {
transform: translateY(0.5rem)
scale(
calc(100% - var(--toast-index) * 5%),
calc(100% - var(--toast-index) * 2%)
);
}
to {
transform: translateY(0)
scale(
calc(100% - var(--toast-index) * 5%),
calc(100% - var(--toast-index) * 2%)
);
}
}
@keyframes slide-up-odd {
from {
transform: translateY(0.5rem)
scale(
calc(100% - var(--toast-index) * 5%),
calc(100% - var(--toast-index) * 2%)
);
}
to {
transform: translateY(0)
scale(
calc(100% - var(--toast-index) * 5%),
calc(100% - var(--toast-index) * 2%)
);
}
}
.toast[data-top] {
animation: slide-in 0.2s ease-out;
}
.toast-container:hover .toast[data-top],
.toast-container:focus-within .toast[data-top] {
animation: slide-in 0 ease-out;
}
@keyframes slide-in {
from {
opacity: 0;
transform: translateY(100%)
scale(
calc(110% - var(--toast-index) * 5%),
calc(110% - var(--toast-index) * 2%)
);
}
to {
opacity: 1;
transform: translateY(0)
scale(
calc(100% - var(--toast-index) * 5%),
calc(100% - var(--toast-index) * 2%)
);
}
}
.toast-container:hover .toast,
.toast-container:focus-within .toast {
margin-top: var(--toast-padding);
filter: brightness(1);
opacity: 1;
transform: scale(calc(100%));
}
.toast[data-type="success"] {
background-color: var(--primary-success-color);
color: var(--secondary-success-color);
}
.toast[data-type="error"] {
background-color: var(--primary-error-color);
color: var(--contrast-error-color);
}
.toast[data-type="warning"] {
background-color: var(--primary-warning-color);
color: var(--secondary-warning-color);
}
.toast[data-type="info"] {
background-color: var(--primary-info-color);
color: var(--secondary-info-color);
}
.toast-content {
flex: 1;
margin-right: 8px;
transition: filter 0.2s ease;
}
.toast-title {
margin-bottom: 4px;
color: var(--secondary-color-4);
font-weight: 600;
}
.toast-description {
color: var(--secondary-color-3);
font-size: 0.875rem;
}
.toast-close {
align-self: flex-start;
padding: 0;
border: none;
margin: 0;
background: none;
color: var(--secondary-color-3);
cursor: pointer;
font-size: 18px;
line-height: 1;
}
.toast-close:hover {
color: var(--secondary-color-1);
}

45
packages/web/src/main.rs Normal file
View File

@@ -0,0 +1,45 @@
use dioxus::prelude::*;
use views::{Blog, Home};
mod views;
#[derive(Debug, Clone, Routable, PartialEq)]
#[rustfmt::skip]
enum Route {
#[layout(WebNavbar)]
#[route("/")]
Home {},
#[route("/blog/:id")]
Blog { id: i32 },
}
const FAVICON: Asset = asset!("/assets/favicon.ico");
const MAIN_CSS: Asset = asset!("/assets/main.css");
fn main() {
dioxus::launch(App);
}
#[component]
fn App() -> Element {
// Build cool things ✌️
rsx! {
// Global app resources
document::Link { rel: "icon", href: FAVICON }
document::Link { rel: "stylesheet", href: MAIN_CSS }
Router::<Route> {}
}
}
/// A web-specific Router around the shared `Navbar` component
/// which allows us to use the web-specific `Route` enum.
#[component]
fn WebNavbar() -> Element {
rsx! {
Outlet::<Route> {}
}
}

View File

@@ -0,0 +1,30 @@
use crate::Route;
use dioxus::prelude::*;
const BLOG_CSS: Asset = asset!("/assets/blog.css");
#[component]
pub fn Blog(id: i32) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: BLOG_CSS}
div {
id: "blog",
// Content
h1 { "This is blog #{id}!" }
p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." }
// Navigation links
Link {
to: Route::Blog { id: id - 1 },
"Previous"
}
span { " <---> " }
Link {
to: Route::Blog { id: id + 1 },
"Next"
}
}
}
}

View File

@@ -0,0 +1,6 @@
use dioxus::prelude::*;
#[component]
pub fn Home() -> Element {
rsx! {}
}

View File

@@ -0,0 +1,5 @@
mod home;
pub use home::Home;
mod blog;
pub use blog::Blog;