diff --git a/lib/mcp_registry_web/components/layouts.ex b/lib/mcp_registry_web/components/layouts.ex index fc8b11c..4ab8ece 100644 --- a/lib/mcp_registry_web/components/layouts.ex +++ b/lib/mcp_registry_web/components/layouts.ex @@ -38,6 +38,13 @@ defmodule McpRegistryWeb.Layouts do default: false, doc: "drop the reading-width cap, for the landing page's full-bleed sections" + attr :sponsors, :boolean, + default: false, + doc: """ + put the content in a main column with the sponsor sidebar beside it. A page + with a sidebar of its own (a listing) keeps it, and uses the same hook. + """ + slot :rail, doc: """ A full-width bar pinned under the site header — breadcrumbs on the left, @@ -96,8 +103,18 @@ defmodule McpRegistryWeb.Layouts do
-
- {render_slot(@inner_block)} +
+ <%= if @sponsors do %> +
+
{render_slot(@inner_block)}
+ <.sponsor_sidebar class="lg:col-span-4" /> +
+ <% else %> + {render_slot(@inner_block)} + <% end %>
@@ -227,7 +244,80 @@ defmodule McpRegistryWeb.Layouts do end @doc """ - The sponsored block: four square slots, two up. + A right-hand sidebar that scrolls with the page and then holds, holding the + sponsored block below whatever the caller puts in it. + + The sidebar is taller than the window -- five 250px tiles alone are -- so + pinning it by its top, the usual sticky sidebar, would show only its first + screenful until the main column ran out, sometimes 10,000 words later. The + `.StickySidebar` hook pins it by its bottom instead: it scrolls with the page + until its last item is in view, then stays. + + ## Examples + + + + A page with its own sidebar can use the behaviour without the component: + `phx-hook="McpRegistryWeb.Layouts.StickySidebar"`, plus + `phx-mounted={JS.ignore_attributes(["style"])}`. + """ + attr :id, :string, default: "sponsor-sidebar" + attr :class, :any, default: nil + slot :inner_block + + def sponsor_sidebar(assigns) do + ~H""" + + """ + end + + @doc """ + The sponsored block: five square slots, one per row -- the book first and + last, and the three slots for sale between. Lives here rather than in `CoreComponents` because it is site chrome: it belongs to the page frame, not to the listing being described, and any page @@ -256,15 +346,22 @@ defmodule McpRegistryWeb.Layouts do @enquiry_subject "Interested Sponsor for MCP Harbor" @enquiry_body "I'm interested in bidding $____ for a Sponsor position on MCP Harbor." + @book_slot %{ + file: "Book.png", + alt: "MCP Server Optimization — the book behind this registry", + kind: :book + } + + # The book opens and closes the block. The sidebar is taller than the window + # and settles with its bottom in view, so the last tile is the one a reader + # keeps seeing for the rest of a long page -- and the first is the one they + # see before they scroll at all. @sponsor_slots [ - %{ - file: "Book.png", - alt: "MCP Server Optimization — the book behind this registry", - kind: :book - }, + @book_slot, %{file: "sponsor-1.png", alt: "Sponsor slot available — email to enquire", kind: :enquiry}, %{file: "sponsor-2.png", alt: "Sponsor slot available — email to enquire", kind: :enquiry}, - %{file: "sponsor-3.png", alt: "Sponsor slot available — email to enquire", kind: :enquiry} + %{file: "sponsor-3.png", alt: "Sponsor slot available — email to enquire", kind: :enquiry}, + @book_slot ] def sponsors(assigns) do diff --git a/lib/mcp_registry_web/live/changelog_live.ex b/lib/mcp_registry_web/live/changelog_live.ex index 8f39453..c64e23f 100644 --- a/lib/mcp_registry_web/live/changelog_live.ex +++ b/lib/mcp_registry_web/live/changelog_live.ex @@ -31,7 +31,7 @@ defmodule McpRegistryWeb.ChangelogLive do @impl true def render(assigns) do ~H""" - +

What changed in MCP servers diff --git a/lib/mcp_registry_web/live/server_live/agent.ex b/lib/mcp_registry_web/live/server_live/agent.ex index 98a6804..2020867 100644 --- a/lib/mcp_registry_web/live/server_live/agent.ex +++ b/lib/mcp_registry_web/live/server_live/agent.ex @@ -103,7 +103,7 @@ defmodule McpRegistryWeb.ServerLive.Agent do @impl true def render(assigns) do ~H""" - + <:rail>