Skip to content
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
6 changes: 3 additions & 3 deletions src/components/community_teams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ pub fn CommunityTeams() -> impl IntoView {
let steering_committee = create_steering_committee();

view! {
<section class="background_primary px-4 py-6 md:px-32">
<section class="background_primary px-4 py-6 md:px-16 lg:px-32">
<div class="flex flex-col md:flex-row gap-16 mb-20">
<div class="w-full md:w-[950px]">
<div class="flex flex-col items-start w-full md:flex-1">
<span class="h1 break-words w-full block text-left">
{"How ODP is built by its community"}
</span>
</div>
<div class="flex flex-col justify-start w-full md:max-w-[900px]" style="flex: 1;">
<div class="flex flex-col justify-start w-full md:flex-1">
<span class="p2 break-words w-full block text-left">

{"The Open Device Partnership (ODP) is a collaborative open-source initiative designed to promote cooperative innovation in firmware development through contribution and transparency."}
Expand Down
2 changes: 1 addition & 1 deletion src/components/documentation_training.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub const DEFAULT_DOC_LINKS: &[DocLink] = &[
#[component]
pub fn DocumentationTraining(#[prop(default = DEFAULT_DOC_LINKS.to_vec())] links: Vec<DocLink>) -> impl IntoView {
view! {
<section class="flex flex-col md:flex-row items-start background_primary w-full overflow-x-hidden px-4 py-8 md:py-16 md:px-32">
<section class="flex flex-col md:flex-row items-start background_primary w-full overflow-x-hidden px-4 py-8 md:py-16 md:px-16 lg:px-32">
<div class="flex flex-col items-start w-full" style="align-items: flex-start;">
<ThemedIcon
name="documentation"
Expand Down
76 changes: 63 additions & 13 deletions src/components/header.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
use crate::components::themed_icon::ThemedIcon;
use leptos::ev;
use leptos::prelude::RwSignal;
use leptos::prelude::*;
use leptos_router::components::A;

#[component]
pub fn Header(#[prop(optional, default = "header_background")] background_class: &'static str) -> impl IntoView {
let menu_open = RwSignal::new(false);
let close_menu = move || menu_open.set(false);

// ESC closes the mobile menu when it is open.
window_event_listener(ev::keydown, move |e| {
if e.key() == "Escape" && menu_open.get_untracked() {
menu_open.set(false);
}
});

view! {
<header class=format!(
"w-full h-[80px] md:h-[160px] px-2 md:px-32 {} flex items-center justify-between z-50 m-0 p-0 relative",
"w-full h-[80px] lg:h-[160px] px-4 sm:px-8 md:px-16 {} flex items-center justify-between z-50 m-0 p-0 relative",
background_class,
)>
<div class="flex items-center space-x-6">
<div class="flex items-center space-x-6 flex-shrink-0">
<ThemedIcon
name="odplogo"
alt="ODP Logo"
class="w-[100px] h-[34.5px] md:w-[149px] md:h-[51.43px] object-contain"
class="w-[120px] h-[41px] sm:w-[140px] sm:h-[48px] lg:w-[180px] lg:h-[62px] object-contain"
/>
</div>

<button
class="md:hidden flex flex-col justify-center items-center w-10 h-10 p-2 focus:outline-none"
aria-label="Open menu"
class="lg:hidden flex flex-col justify-center items-center w-10 h-10 p-2 focus:outline-none"
aria-label=move || if menu_open.get() { "Close menu" } else { "Open menu" }
aria-expanded=move || if menu_open.get() { "true" } else { "false" }
aria-controls="primary-mobile-nav"
on:click=move |_| menu_open.update(|v| *v = !*v)
>
<span class="block w-6 h-0.5 bg-black dark:bg-white mb-1"></span>
<span class="block w-6 h-0.5 bg-black dark:bg-white mb-1"></span>
<span class="block w-6 h-0.5 bg-black dark:bg-white"></span>
</button>

<nav class="hidden md:flex [column-gap:25px]">
<nav class="hidden lg:flex [column-gap:25px]" aria-label="Primary">
<NavButton href="/getting-started" label="Getting Started" />
<NavButton href="/projects" label="Projects" />
<ExternalNavButton
Expand All @@ -40,26 +52,47 @@ pub fn Header(#[prop(optional, default = "header_background")] background_class:
<NavButton href="/home" label="Home" />
</nav>

// Backdrop: catches clicks outside the open mobile menu and dismisses it.
<div
class="fixed inset-0 z-40 lg:hidden"
style=move || { if menu_open.get() { "display: block;" } else { "display: none;" } }
on:click=move |_| close_menu()
aria-hidden="true"
></div>

<nav
class="absolute right-0 top-full w-[80vw] max-w-xs background_primary flex-col items-end px-4 py-4 space-y-2 shadow-lg md:hidden transition-all duration-200"
id="primary-mobile-nav"
aria-label="Primary"
class="absolute right-0 top-full w-[80vw] max-w-xs background_primary flex-col items-end px-4 py-4 space-y-2 shadow-lg lg:hidden transition-all duration-200 z-50"
style=move || if menu_open.get() { "display: flex;" } else { "display: none;" }
>
<NavButton href="/getting-started" label="Getting Started" mobile=true />
<NavButton href="/projects" label="Projects" mobile=true />
<NavButton
href="/getting-started"
label="Getting Started"
mobile=true
on_navigate=close_menu
/>
<NavButton href="/projects" label="Projects" mobile=true on_navigate=close_menu />
<ExternalNavButton
href="https://opendevicepartnership.github.io/documentation/"
label="Library"
mobile=true
on_navigate=close_menu
/>
<NavButton href="/community" label="Community" mobile=true />
<NavButton href="/home" label="Home" mobile=true />
<NavButton href="/community" label="Community" mobile=true on_navigate=close_menu />
<NavButton href="/home" label="Home" mobile=true on_navigate=close_menu />
</nav>
</header>
}
}

#[component]
fn NavButton(href: &'static str, label: &'static str, #[prop(optional)] mobile: bool) -> impl IntoView {
fn NavButton(
href: &'static str,
label: &'static str,
#[prop(optional)] mobile: bool,
#[prop(optional, into)] on_navigate: Option<Callback<()>>,
) -> impl IntoView {
let location = leptos_router::hooks::use_location();
let is_active = move || location.pathname.get().starts_with(href);

Expand All @@ -71,14 +104,25 @@ fn NavButton(href: &'static str, label: &'static str, #[prop(optional)] mobile:
class:odp-header-btn-active=is_active
class:odp-header-btn-active-text=is_active
class:w-full=mobile
attr:aria-current=move || if is_active() { Some("page") } else { None }
on:click=move |_| {
if let Some(cb) = on_navigate {
cb.run(());
}
}
>
{label}
</A>
}
}

#[component]
fn ExternalNavButton(href: &'static str, label: &'static str, #[prop(optional)] mobile: bool) -> impl IntoView {
fn ExternalNavButton(
href: &'static str,
label: &'static str,
#[prop(optional)] mobile: bool,
#[prop(optional, into)] on_navigate: Option<Callback<()>>,
) -> impl IntoView {
view! {
<a
href=href
Expand All @@ -87,6 +131,12 @@ fn ExternalNavButton(href: &'static str, label: &'static str, #[prop(optional)]
if mobile { " w-full" } else { "" },
)
target="_blank"
rel="noopener noreferrer"
on:click=move |_| {
if let Some(cb) = on_navigate {
cb.run(());
}
}
>
{label}
</a>
Expand Down
55 changes: 12 additions & 43 deletions src/components/image_button.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,23 @@
use leptos::prelude::*;

/// Rounded image rendered as a link.
///
/// Sizing is purely declarative via Tailwind utilities passed in `class`.
/// The default `aspect-square max-w-[350px]` matches the landing-page
/// tiles; call sites override the cap when the surrounding layout calls
/// for a larger image. There is no per-instance `<style>` injection --
/// the image scales fluidly with the viewport up to the cap and the
/// aspect-ratio utility keeps the rendered shape square.
#[component]
pub fn ImageButton(
#[prop(into)] href: String,
#[prop(into)] img_src: String,
#[prop(into, default = String::from("Button Image"))] alt: String,
#[prop(default = 350)] width: u32,
#[prop(default = 320)] height: u32,
#[prop(default = None)] mobile_width: Option<u32>,
#[prop(default = None)] mobile_height: Option<u32>,
#[prop(into, default = String::from("aspect-square max-w-[350px]"))] class: String,
) -> impl IntoView {
view! {
<a
href=href
style="
display: inline-block;
border: none;
background: none;
padding: 0;
cursor: pointer;
text-decoration: none;
"
>
<style>
{if let (Some(mw), Some(mh)) = (mobile_width, mobile_height) {
format!(
"@media (max-width: 767px) {{ img[alt='{}'] {{ width: {}px !important; height: {}px !important; }} }}",
alt,
mw,
mh,
)
} else {
String::new()
}}
</style>
<img
src=img_src
alt=alt
style=format!(
"
width: {}px;
height: {}px;
border-radius: 45.7px;
object-fit: cover;
display: block;
",
width,
height,
)
/>
<a href=href class=format!("inline-block w-full overflow-hidden rounded-3xl {}", class)>
<img src=img_src alt=alt class="w-full h-full object-cover block" />
</a>
}
}
}
23 changes: 13 additions & 10 deletions src/components/landing_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ use leptos::prelude::*;
#[component]
pub fn LandingPage() -> impl IntoView {
view! {
<div class="background_primary px-2 md:px-32" style="width: auto; height: auto;">
<div
class="background_primary px-4 sm:px-8 md:px-16 lg:px-32"
style="width: auto; height: auto;"
>
<div class="flex flex-col md:flex-row gap-20 items-start">
<div class="flex flex-col items-start flex-shrink-0 w-full md:w-[800px]">
<div class="flex flex-col items-start min-w-0 w-full md:flex-1">
<span class="h1 break-words w-full block text-left">
{"An Open Collaboration for Secure, Modern Devices"}
</span>
</div>
<div class="flex flex-col items-start flex-shrink min-w-0 w-full md:w-[650px]">
<div class="flex flex-col items-start min-w-0 w-full md:flex-1">
<span class="p1 break-words w-full block text-left">
{"The Open Device Partnership (ODP) is a global initiative to make it easier for developers and device makers to build secure, efficient, and reliable client devices for cross-platform needs and certified environments."}
<br /><br />
Expand All @@ -21,11 +24,11 @@ pub fn LandingPage() -> impl IntoView {
</div>
</div>
</div>
<section class="background_secondary px-2 md:px-32 py-20">
<section class="background_secondary px-4 sm:px-8 md:px-16 lg:px-32 py-20">
<div>
<h2 class="h2 text-left">{"Value Proposition"}</h2>
<div class="flex flex-col md:flex-row gap-16">
<div class="flex flex-col items-start w-full md:w-[400px]">
<div class="flex flex-col items-start w-full md:flex-1">
<ThemedIcon name="lock" alt="Security Icon" class="icon" />
<span class="h3 break-words w-full block text-left">
{"Enhanced Security"}
Expand All @@ -34,7 +37,7 @@ pub fn LandingPage() -> impl IntoView {
{"Security threats continue to evolve. ODP takes a proactive approach: reducing attack surfaces, using secure hardware features, leveraging the memory-safe Rust language, and designing every component with security-first principles."}
</span>
</div>
<div class="flex flex-col items-start w-full md:w-[400px]">
<div class="flex flex-col items-start w-full md:flex-1">
<ThemedIcon name="checkcircle" alt="Interoperability Icon" class="icon" />
<span class="h3 break-words w-full block text-left">
{"Standardization"}
Expand All @@ -43,7 +46,7 @@ pub fn LandingPage() -> impl IntoView {
{"Many device firmware components are 'invisible plumbing' - necessary but costly to build and maintain. ODP's standards-based approach simplifies this infrastructure, maximizing reuse across devices, architectures (x86 and ARM), and generations."}
</span>
</div>
<div class="flex flex-col items-start w-full md:w-[400px]">
<div class="flex flex-col items-start w-full md:flex-1">
<ThemedIcon name="fastforward" alt="Innovation Icon" class="icon" />
<span class="h3 break-words w-full block text-left">
{"Accelerated Development"}
Expand All @@ -57,7 +60,7 @@ pub fn LandingPage() -> impl IntoView {
</section>

// ODP Projects Section
<section class="background_primary px-2 md:px-32 py-32">
<section class="background_primary px-4 sm:px-8 md:px-16 lg:px-32 py-32">
<div style="max-width: 960px;">
<h2 class="h2 text-left">{"ODP Projects"}</h2>
<p class="p2" style="text-align: left; max-width: 100%;">
Expand All @@ -69,7 +72,7 @@ pub fn LandingPage() -> impl IntoView {
</section>

// Boot Firmware Buttons Section
<section class="background_primary px-2 md:px-32 pb-32">
<section class="background_primary px-4 sm:px-8 md:px-16 lg:px-32 pb-32">
<div class="flex flex-col md:flex-row gap-16 justify-start">
<ImageButton
href="/boot-firmware"
Expand All @@ -90,7 +93,7 @@ pub fn LandingPage() -> impl IntoView {
</section>

// Two Columns Section
<section class="background_primary px-2 md:px-32 py-20">
<section class="background_primary px-4 sm:px-8 md:px-16 lg:px-32 py-20">
<div class="flex flex-col md:flex-row gap-16">
<div class="flex flex-col items-start" style="flex: 1;">
<span class="h3 block text-left">{"Partner-Oriented Vision"}</span>
Expand Down
14 changes: 7 additions & 7 deletions src/components/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use leptos_router::components::A;
pub fn Main() -> impl IntoView {
view! {
<main class="background_primary">
<div class="mx-auto flex flex-col md:flex-row items-start justify-between w-full px-2 sm:px-4">
<div class="pl-0 md:pl-32 flex flex-col gap-6 w-full md:w-auto">
<div class="mx-auto flex flex-col lg:flex-row items-start justify-between w-full px-2 sm:px-4">
<div class="pl-0 lg:pl-32 flex flex-col gap-6 w-full lg:w-auto">
<h1 class="h1 py-4 w-full max-w-full text-left break-words">
"Building the Future of Trusted System Software Together"
</h1>
Expand All @@ -16,10 +16,10 @@ pub fn Main() -> impl IntoView {
</p>
</div>

<div class="flex flex-col w-full md:w-auto mt-4 md:mt-0">
<div class="flex flex-col w-full lg:w-auto mt-4 lg:mt-0">
<div
style="border: none; text-decoration: none;"
class="flex background_secondary w-full md:w-[478px] h-[120px] md:h-[176px] items-center justify-center px-4 md:px-16"
class="flex background_secondary w-full lg:w-[478px] h-[120px] lg:h-[176px] items-center justify-center px-4 lg:px-16"
>
<A href="/getting-started">
<div class="flex flex-row items-center justify-center gap-4 w-full max-w-full">
Expand All @@ -31,7 +31,7 @@ pub fn Main() -> impl IntoView {

<div
style="border: none; text-decoration: none;"
class="flex background_tertiary w-full md:w-[478px] h-[120px] md:h-[176px] items-center justify-center px-4 md:px-16"
class="flex background_tertiary w-full lg:w-[478px] h-[120px] lg:h-[176px] items-center justify-center px-4 lg:px-16"
>
<A href="/projects">
<div class="flex flex-row items-center justify-center gap-4 w-full max-w-full">
Expand All @@ -45,7 +45,7 @@ pub fn Main() -> impl IntoView {

<div class="flex flex-col pt-10 px-2 sm:px-4 md:pl-[117px] w-full">
<div class="flex flex-col lg:flex-row items-start w-full gap-4">
<div class="flex flex-col items-start w-full lg:w-[423px] mr-0 lg:mr-16 mb-6 lg:mb-0">
<div class="flex flex-col items-start w-full lg:flex-1 mr-0 lg:mr-16 mb-6 lg:mb-0">
<ThemedIcon
name="video"
alt="Video Icon"
Expand All @@ -67,7 +67,7 @@ pub fn Main() -> impl IntoView {
</span>
</div>
<div
class="w-full lg:w-[1200px] aspect-video rounded-lg overflow-hidden"
class="w-full lg:flex-[2] aspect-video rounded-lg overflow-hidden"
style="max-width:100vw;"
>
<iframe
Expand Down
2 changes: 1 addition & 1 deletion src/components/partners_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const PARTNERS: &[PartnerInfo] = &[
#[component]
pub fn PartnersGrid() -> impl IntoView {
view! {
<section class="background_primary px-4 md:px-32 py-20">
<section class="background_primary px-4 sm:px-8 md:px-16 lg:px-32 py-20">
<div class="mb-16">
<span class="h1 break-words w-full block text-left">{"Our Partners"}</span>
</div>
Expand Down
Loading
Loading