0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-07 13:19:19 +08:00
discourse/plugins/styleguide/spec/system/styleguide_sidebar_spec.rb
Sérgio Saquetim 1506fcaec2
UX: Move the styleguide navigation into the main sidebar (#42058)
The styleguide renders its own navigation column beside Discourse's
sidebar. The two take
roughly a third of the viewport between them, and the forum's sections —
Topics, Categories,
Tags, Channels — have nothing to do with the component being read about.

This registers the styleguide's section list as a hidden sidebar panel
that the `styleguide`
route claims on entry and releases on exit, then deletes the plugin's
own column. It follows
the arrangement `/admin` already uses.

### Before
<img width="1400" height="1200" alt="before-light"
src="https://github.com/user-attachments/assets/c6b05ad9-a664-4883-8dd1-b80cd3c31432"
/>
<img width="1400" height="1200" alt="before-dark"
src="https://github.com/user-attachments/assets/14e3f320-97a2-4256-8473-ed737577b422"
/>

### After
<img width="1400" height="1200"
alt="desktop-foundation-light-styleguide-sidebar"
src="https://github.com/user-attachments/assets/18b5f5ca-25d8-4b01-a4f1-618c0f87c09a"
/>
<img width="1400" height="1200"
alt="desktop-foundation-dark-styleguide-sidebar"
src="https://github.com/user-attachments/assets/8ffa2423-1a5f-468f-9826-f4fd2dc983c3"
/>


### Notes

- Sections are built in a cached getter over `allCategories` rather than
pushed through
`addSidebarSection`. `allCategories` memoizes on first call, so reading
it lazily keeps the
list complete for plugins that add sections from an initializer, and
avoids the
  re-registration a push-based panel needs in order to redraw.
- `isForcingSidebar` is set while the panel is active. The nav used to
render unconditionally,
so without it a reader whose `navigation_menu` is the header dropdown
would silently lose it.
- On mobile the sidebar is suppressed and the panel appears in the
hamburger, same as the admin
  panel.
- The panel is filterable, which the old markup had no equivalent for.
- Section and link names are dasherized (`styleguide-category-atoms`,
`styleguide-section-buttons`), which the sidebar base classes document
as the contract.

### Section header

Section pages now use `DPageHeader`. The breadcrumb row lands level with
the sidebar's own
header, which is what makes the title line up with the filter field
rather than floating
between the sidebar's two rows.

The color toggle moves onto that row and becomes a three-way
light/dark/auto selector,
reusing core's `sidebar.footer.interface_color_selector` strings and
icons. Color mode is
page chrome rather than an action on the page, so it belongs on the
utility row rather than
beside the title. It now reads the applied stylesheet instead of
remembering the mode it last
set, which matters because moving between sections rebuilds the
component — previously the
first click after navigating re-applied the mode already showing and
appeared to do nothing.

### Unknown sections

`sectionById` returns nothing for a section that does not exist, and the
show template then
rendered a title from an undefined key, throwing in `I18n.lookup`. The
route now redirects to
`/404`, matching how category routes handle a missing record. This is a
pre-existing bug
rather than a regression from this PR, fixed here because the header
work touches the same
template.

The smoke test's nav scrape keys on `data-section-name` rather than the
header's rendered
text, which only matched because the stylesheet uppercased it.
2026-07-27 18:32:34 -03:00

98 lines
3.2 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe "Styleguide sidebar panel" do
include ThemeScreenshotMarker
fab!(:admin)
let(:styleguide) { PageObjects::Pages::Styleguide.new }
let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new }
let(:sidebar_dropdown) { PageObjects::Components::SidebarHeaderDropdown.new }
let(:filter) { PageObjects::Components::Filter.new }
before do
SiteSetting.styleguide_enabled = true
SiteSetting.navigation_menu = "sidebar"
sign_in(admin)
end
it "replaces the forum sidebar with the styleguide's own navigation" do
visit "/styleguide/atoms/buttons"
expect(sidebar).to be_visible
expect(page).to have_css(".sidebar-sections.styleguide-panel")
%w[syntax atoms molecules organisms].each do |category|
expect(sidebar).to have_section("styleguide-category-#{category}")
end
# The forum's own sections are displaced rather than merely pushed down.
expect(sidebar).to have_no_section("categories")
screenshot_marker(label: "styleguide-sidebar", only: :desktop)
end
it "links to a section without leaking a group query param" do
visit "/styleguide"
expect(sidebar).to have_section_link("Buttons", href: "/styleguide/atoms/buttons")
end
it "marks the current section's link as active" do
visit "/styleguide/atoms/buttons"
expect(styleguide).to have_active_nav_link("Buttons")
end
it "hands the sidebar back when leaving the styleguide" do
visit "/styleguide/atoms/buttons"
expect(sidebar).to have_no_section("categories")
sidebar.click_back_to_forum
expect(sidebar).to have_section("categories")
expect(page).to have_no_css(".sidebar-sections.styleguide-panel")
end
it "does not offer a switch button for the panel" do
visit "/styleguide"
expect(sidebar).to have_no_switch_button("styleguide")
end
# The styleguide's nav used to render unconditionally, so a reader who prefers the header
# dropdown must not lose it now that it lives in the sidebar.
it "renders for a reader whose navigation menu preference is the header dropdown" do
SiteSetting.navigation_menu = NavigationMenuSiteSetting::HEADER_DROPDOWN
visit "/styleguide/atoms/buttons"
expect(page).to have_css(".sidebar-sections.styleguide-panel")
end
# Mobile never renders the fixed sidebar, so the panel reaches the reader through the header
# dropdown instead. That is a separate path from the desktop one and needs its own coverage.
it "reaches the styleguide navigation through the header dropdown on mobile", mobile: true do
visit "/styleguide"
sidebar_dropdown.click
expect(page).to have_css(".sidebar-sections.styleguide-panel")
expect(sidebar).to have_section("styleguide-category-atoms")
expect(sidebar).to have_no_section("categories")
sidebar.click_link_in_section("styleguide-category-atoms", "styleguide-section-buttons")
expect(page).to have_current_path("/styleguide/atoms/buttons")
expect(sidebar_dropdown).to be_hidden
end
it "filters the sections" do
visit "/styleguide"
filter.filter("typography")
expect(sidebar).to have_section_link("Typography")
expect(sidebar).to have_no_section_link("Buttons")
end
end