From 28b0594116f34211f36b220783400607171268af Mon Sep 17 00:00:00 2001 From: Sundram Gupta Date: Tue, 21 Jul 2026 23:42:29 +0530 Subject: [PATCH] fix(oc-docs): fill playground sidebar icon when open, drop method bg in url bar Thread the existing sidebarOpen state through the docks into PlaygroundHeader so the sidebar-toggle icon renders its panel column filled (and sets aria-pressed) while the sidebar is open. Remove the pill background from the playground query bar method badge so it matches the docs url bar (colored text, no background). --- .../e2e/tests/playground/playground.spec.ts | 3 +++ .../src/assets/icons/SidebarToggleIcon.tsx | 8 +++++++- .../PlaygroundView/QueryBar/StyledWrapper.ts | 4 +--- .../src/components/Playground/Playground.tsx | 1 + .../PlaygroundHeader/PlaygroundHeader.spec.tsx | 16 ++++++++++++++++ .../PlaygroundHeader/PlaygroundHeader.tsx | 5 ++++- .../docks/BottomSheetDock/BottomSheetDock.tsx | 3 +++ .../Playground/docks/InlineDock/InlineDock.tsx | 4 +++- .../Playground/docks/MobileDock/MobileDock.tsx | 4 +++- .../Playground/docks/ModalDock/ModalDock.tsx | 4 +++- 10 files changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/oc-docs/e2e/tests/playground/playground.spec.ts b/packages/oc-docs/e2e/tests/playground/playground.spec.ts index 4c871e4a..94f241f5 100644 --- a/packages/oc-docs/e2e/tests/playground/playground.spec.ts +++ b/packages/oc-docs/e2e/tests/playground/playground.spec.ts @@ -106,10 +106,13 @@ test.describe('playground docks (desktop)', () => { test('header toggle hides and restores the playground sidebar', async ({ page, playground }) => { await page.goto(openAt('bottom')); await expect(playground.sidebarPanel).toBeVisible(); + await expect(playground.sidebarToggle).toHaveAttribute('aria-pressed', 'true'); await playground.sidebarToggle.click(); await expect(playground.sidebarPanel).toHaveCount(0); + await expect(playground.sidebarToggle).toHaveAttribute('aria-pressed', 'false'); await playground.sidebarToggle.click(); await expect(playground.sidebarPanel).toBeVisible(); + await expect(playground.sidebarToggle).toHaveAttribute('aria-pressed', 'true'); }); test('clicking a request in the sidebar loads it, gear opens environments', async ({ page, playground }) => { diff --git a/packages/oc-docs/src/assets/icons/SidebarToggleIcon.tsx b/packages/oc-docs/src/assets/icons/SidebarToggleIcon.tsx index ec4b5ac9..40329bf9 100644 --- a/packages/oc-docs/src/assets/icons/SidebarToggleIcon.tsx +++ b/packages/oc-docs/src/assets/icons/SidebarToggleIcon.tsx @@ -1,9 +1,15 @@ import React from 'react'; import { baseIconProps } from './baseIconProps'; -export const SidebarToggleIcon: React.FC = () => ( +interface SidebarToggleIconProps { + /** Fills the sidebar column when the playground sidebar is open. */ + active?: boolean; +} + +export const SidebarToggleIcon: React.FC = ({ active = false }) => ( + {active && } ); diff --git a/packages/oc-docs/src/components/Playground/Content/Views/PlaygroundView/QueryBar/StyledWrapper.ts b/packages/oc-docs/src/components/Playground/Content/Views/PlaygroundView/QueryBar/StyledWrapper.ts index 10d402b0..421efea2 100644 --- a/packages/oc-docs/src/components/Playground/Content/Views/PlaygroundView/QueryBar/StyledWrapper.ts +++ b/packages/oc-docs/src/components/Playground/Content/Views/PlaygroundView/QueryBar/StyledWrapper.ts @@ -58,9 +58,7 @@ export const StyledWrapper = styled.div` } .method-badge { - padding: 0.125rem 0.5rem; - border-radius: var(--oc-radius); - background-color: color-mix(in srgb, currentColor 12%, transparent); + padding: 0; } .actions { diff --git a/packages/oc-docs/src/components/Playground/Playground.tsx b/packages/oc-docs/src/components/Playground/Playground.tsx index 40303569..45e47eb9 100644 --- a/packages/oc-docs/src/components/Playground/Playground.tsx +++ b/packages/oc-docs/src/components/Playground/Playground.tsx @@ -67,6 +67,7 @@ const Playground: React.FC = ({ openNonce }) => { const shared = { dock: effectiveDock, onDockChange: setDock, + sidebarOpen, onToggleSidebar: () => setSidebarOpen((value) => !value), onClose: closePlayground, }; diff --git a/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.spec.tsx b/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.spec.tsx index 0ab823e4..9c308ff8 100644 --- a/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.spec.tsx +++ b/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.spec.tsx @@ -22,4 +22,20 @@ describe('PlaygroundHeader', () => { expect(html).toContain('playground-sidebar-toggle'); expect(html).toContain('playground-close'); }); + + it('marks the sidebar toggle pressed and fills the icon when the sidebar is open', () => { + const html = renderToStaticMarkup( + + ); + expect(html).toContain('aria-pressed="true"'); + expect(html).toContain('fill="currentColor"'); + }); + + it('leaves the sidebar toggle unpressed and the icon unfilled when the sidebar is closed', () => { + const html = renderToStaticMarkup( + + ); + expect(html).toContain('aria-pressed="false"'); + expect(html).not.toContain('fill="currentColor"'); + }); }); diff --git a/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.tsx b/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.tsx index 12d1e1df..3a7c135f 100644 --- a/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.tsx +++ b/packages/oc-docs/src/components/Playground/PlaygroundHeader/PlaygroundHeader.tsx @@ -9,6 +9,7 @@ interface PlaygroundHeaderProps { dock: DockMode; onDockChange: (dock: DockMode) => void; showDockSwitcher?: boolean; + sidebarOpen?: boolean; onToggleSidebar: () => void; onClose: () => void; collapsed?: boolean; @@ -20,6 +21,7 @@ const PlaygroundHeader: React.FC = ({ dock, onDockChange, showDockSwitcher = true, + sidebarOpen = false, onToggleSidebar, onClose, collapsed, @@ -32,10 +34,11 @@ const PlaygroundHeader: React.FC = ({ className="header-sidebar-toggle" label="Toggle playground sidebar" title="Toggle sidebar" + aria-pressed={sidebarOpen} data-testid="playground-sidebar-toggle" onClick={onToggleSidebar} > - + diff --git a/packages/oc-docs/src/components/Playground/docks/BottomSheetDock/BottomSheetDock.tsx b/packages/oc-docs/src/components/Playground/docks/BottomSheetDock/BottomSheetDock.tsx index 9055ef28..2d0ae025 100644 --- a/packages/oc-docs/src/components/Playground/docks/BottomSheetDock/BottomSheetDock.tsx +++ b/packages/oc-docs/src/components/Playground/docks/BottomSheetDock/BottomSheetDock.tsx @@ -12,6 +12,7 @@ const COLLAPSE_EPSILON = 8; interface BottomSheetDockProps { dock: DockMode; onDockChange: (dock: DockMode) => void; + sidebarOpen: boolean; onToggleSidebar: () => void; onClose: () => void; /** Bumped on each Try click; re-expands the sheet when it is collapsed. */ @@ -22,6 +23,7 @@ interface BottomSheetDockProps { const BottomSheetDock: React.FC = ({ dock, onDockChange, + sidebarOpen, onToggleSidebar, onClose, openNonce, @@ -72,6 +74,7 @@ const BottomSheetDock: React.FC = ({ void; + sidebarOpen: boolean; onToggleSidebar: () => void; onClose: () => void; children: React.ReactNode; } -const InlineDock: React.FC = ({ dock, onDockChange, onToggleSidebar, onClose, children }) => { +const InlineDock: React.FC = ({ dock, onDockChange, sidebarOpen, onToggleSidebar, onClose, children }) => { const { size, dragging, startDrag } = useDockResize({ axis: 'x', initial: Math.round(window.innerWidth * 0.4), @@ -31,6 +32,7 @@ const InlineDock: React.FC = ({ dock, onDockChange, onToggleSid diff --git a/packages/oc-docs/src/components/Playground/docks/MobileDock/MobileDock.tsx b/packages/oc-docs/src/components/Playground/docks/MobileDock/MobileDock.tsx index 41100dc9..ade129de 100644 --- a/packages/oc-docs/src/components/Playground/docks/MobileDock/MobileDock.tsx +++ b/packages/oc-docs/src/components/Playground/docks/MobileDock/MobileDock.tsx @@ -8,12 +8,13 @@ import { StyledWrapper } from './StyledWrapper'; interface MobileDockProps { dock: DockMode; onDockChange: (dock: DockMode) => void; + sidebarOpen: boolean; onToggleSidebar: () => void; onClose: () => void; children: React.ReactNode; } -const MobileDock: React.FC = ({ dock, onDockChange, onToggleSidebar, onClose, children }) => { +const MobileDock: React.FC = ({ dock, onDockChange, sidebarOpen, onToggleSidebar, onClose, children }) => { // Full-screen phone presentation: lock the docs scroll behind it. No dock // switcher or collapse - there is nowhere to dock on a phone. useLockBodyScroll(); @@ -24,6 +25,7 @@ const MobileDock: React.FC = ({ dock, onDockChange, onToggleSid void; + sidebarOpen: boolean; onToggleSidebar: () => void; onClose: () => void; children: React.ReactNode; } -const ModalDock: React.FC = ({ dock, onDockChange, onToggleSidebar, onClose, children }) => { +const ModalDock: React.FC = ({ dock, onDockChange, sidebarOpen, onToggleSidebar, onClose, children }) => { // Modal is a true full-screen overlay: lock the docs body scroll behind it and // close on Escape (the inline/bottom docks are persistent panels, so they get // neither). Focus containment / focus-return is a tracked follow-up. @@ -28,6 +29,7 @@ const ModalDock: React.FC = ({ dock, onDockChange, onToggleSideb