blessed-rs

repository·main·Indexed 23 days ago

https://github.com/nicoburns/blessed-rs

A web application built with the Rust ecosystem, utilizing Axum for the web server and Dioxus for component-based UI rendering with Server-Side Rendering (SSR). It features a structured layout system including Page, MainContent, and Section components, as well as a TableOfContents component with IntersectionObserver-based active section highlighting.

Tokens
2.5K
Snippets
7
Records
15
Agent score
82%

What's inside blessed-rs

  1. Run Blessed.rs locally

    main

    To run the Blessed.rs project on your local machine, use cargo run and then navigate to http://localhost:3333 in your web browser.

    You can change the default port by setting the PORT environment variable.

    cargo run
  2. Enable automatic recompilation with cargo-watch

    main

    To automatically recompile and re-run the project whenever you save changes, install cargo-watch and use the watch command with the run execution flag.

    cargo install cargo-watch
    cargo watch -x run
  3. Structure of the LearningResourcesPage component

    main

    The LearningResourcesPage is a Dioxus component used to render a structured list of educational resources. It follows a hierarchical pattern using several internal components:

    1. Page: The top-level wrapper that accepts a title and contains the main page content (e.g., h1, p).
    2. MainContent: The primary content container. It accepts an optional toc_sections argument, which is a Vec<TocSection> used to generate a Table of Contents.
    3. Section: Represents a major grouping of content. It requires a section_key (used for linking/identification) and a heading.
    4. Section (Nested): A Section can be nested within another to create subsections. Nested sections use a subsection_key (typically a Cow<'static, str>) to differentiate themselves from the parent section.

    To build a resource page, you define a list of TocSection and TocSubSection objects to drive the navigation, then populate the MainContent with Section components that match those keys.

    #[component]
    pub fn LearningResourcesPage() -> Element {
        let toc_sections = vec![/* ... TocSection definitions ... */];
    
        rsx! {
            Page { title: "Learning Resources".into(),
                h1 { "Learning Resources" }
                MainContent { toc_sections: Some(toc_sections),
                    Section { section_key: "books".into(), heading: "Books",
                        Section {
                            section_key: "books".into(),
                            subsection_key: Cow::from("introductory-books"),
                            heading: "Introductory Books",
                            div { /* content */ }
                        }
                    }
                }
            }
        }
    }
  4. How TableOfContents handles active section highlighting

    main

    The TableOfContents component uses an internal script that relies on the browser's IntersectionObserver API to track which content sections are currently visible on the screen.

    For the highlighting to work, your content sections must meet these criteria:

    1. They must be <section> elements.
    2. They must have the data-toc-section attribute.
    3. Their id must match the generated data-toc-link attribute in the TOC (e.g., if a section has id="section-intro", the TOC will look for li[data-toc-link="section-intro"]).

    When a section enters the viewport, the component adds the active CSS class to the corresponding <li> in the Table of Contents.

  5. Configure server environment variables

    main

    The application uses environment variables to determine the host address and port for the server. If these are not provided, the application defaults to localhost (via ::) on port 3333.

    • HOST: The IP address to bind to (e.g., 127.0.0.1 or ::).
    • PORT: The port number to listen on (e.g., 8080).
  6. Use the Page component for layout structure

    main

    The Page component serves as the top-level layout wrapper for the application. It automatically handles the HTML <head> configuration, including setting the document title, viewport meta tags, and linking essential stylesheets (normalize.css, index.css, fira-sans.css, and github-fork-ribbon.css). It also includes a standard header with a logo and navigation links.

    Props:

    • title: A Cow<'static, str> used to set the page title (formatted as "{title} - Blessed.rs").
    • head: An optional Element to inject additional content into the <head> section.
    • footer: An optional Element to render at the bottom of the <body>.
    • children: The main content of the page.
  7. Use the Section component for content organization

    main

    The Section component is used to structure content into hierarchical sections (H3 or H4) that are compatible with Table of Contents (TOC) generation. It automatically manages IDs for linking and applies data-toc-section attributes.

    Props

    • heading: The text for the section header.
    • description: An optional string rendered as HTML via dangerous_inner_html with the class group-description.
    • level: An optional SectionLevel (H3 or H4). If omitted, the component infers the level based on the presence of a subsection_key (presence of subsection_key results in H4, otherwise H3).
    • section_key: A Cow<'static, str> used to construct the section's ID.
    • subsection_key: An optional Cow<'static, str> used to create a nested subsection ID.
    • children: The content to be rendered inside the section.

    ID Generation Logic

    • If subsection_key is provided: id="section-{section_key}-subsection-{subsection_key}"
    • If subsection_key is NOT provided: id="section-{section_key}"
  8. Use dx_route_cached for optimized Dioxus rendering

    main

    The dx_route_cached function provides an optimized way to serve Dioxus components via Axum by caching the rendered HTML in memory. It uses a DashMap to store the rendered Bytes keyed by the function pointer of the rendering function. This avoids re-rendering the component on subsequent requests.

    To use it, pass a function that returns a Dioxus Element to the handler.

    .route(
        "/crates",
        get(|| dx_route_cached(|| html!(<CrateListPage />))),
    )
  9. Use the TableOfContents component

    main
    The TableOfContents component renders a navigable list of content sections. It accepts a vector of TocSection objects, which can include nested TocSubSection objects. The component automatically includes a script that uses an IntersectionObserver to highlight the currently visible section in the UI by adding an active class to the corresponding list item.
  10. Use the MainContent component for content layout

    main

    The MainContent component manages the layout of the primary content area, specifically handling the relationship between a sidebar and the content body.

    Props:

    • prose: A boolean (defaults to false). When true, it applies a max-width constraint of 800px to the content div to optimize readability.
    • toc_sections: An optional Vec<TocSection> used to populate a LeftSidebar if provided.
    • children: The main content to be rendered in the #content div.

    If toc_sections is provided, the component automatically renders a LeftSidebar alongside the content using a flexbox layout (class: "hflex").