diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index 1a326c62b8..43d3112a73 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -16,9 +16,21 @@ import { RuleOptions } from './types'; -const SIDEBAR_WIDTH = '224px'; +export default ({ theme, sidebar }: RuleOptions) => { + const sidebarWidth = sidebar.isPresent ? `${sidebar.width}px` : '0px'; + const sidebarMargin = sidebar.isPresent ? '16rem' : '0'; -export default ({ theme, sidebar }: RuleOptions) => ` + // Calculate the sidebar position for mobile layouts + let sidebarLeftPosition; + if (!sidebar.isPresent) { + sidebarLeftPosition = '-16rem'; + } else if (sidebar.isPinned) { + sidebarLeftPosition = `calc(-16rem + ${sidebarWidth})`; + } else { + sidebarLeftPosition = 'calc(-16rem + 72px)'; + } + + return ` /*================== Layout ==================*/ /* mkdocs material v9 compat */ @@ -122,12 +134,12 @@ export default ({ theme, sidebar }: RuleOptions) => ` .md-content { max-width: calc(100% - 16rem * 2); - margin-left: 16rem; + margin-left: ${sidebarMargin}; margin-bottom: 50px; } .md-content > .md-sidebar { - left: 16rem; + left: ${sidebarMargin}; } .md-footer { @@ -209,11 +221,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` .md-sidebar--primary { width: 16rem !important; z-index: 200; - left: ${ - sidebar.isPinned - ? `calc(-16rem + ${SIDEBAR_WIDTH})` - : 'calc(-16rem + 72px)' - } !important; + left: ${sidebarLeftPosition} !important; } .md-sidebar--secondary:not([hidden]) { display: none; @@ -269,3 +277,4 @@ export default ({ theme, sidebar }: RuleOptions) => ` } } `; +}; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/types.ts b/plugins/techdocs/src/reader/transformers/styles/rules/types.ts index e2747ad85a..1b6b86cccd 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/types.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/types.ts @@ -22,6 +22,10 @@ import { Theme } from '@material-ui/core/styles'; type BackstageSidebar = { /** Tracks whether the user pinned the sidebar or not. */ isPinned: boolean; + /** Tracks whether a Backstage sidebar is actually present in the DOM. */ + isPresent: boolean; + /** The actual width of the sidebar in pixels, if present. */ + width: number; }; /** diff --git a/plugins/techdocs/src/reader/transformers/styles/transformer.ts b/plugins/techdocs/src/reader/transformers/styles/transformer.ts index b1b1b437c2..fdcb5a2e73 100644 --- a/plugins/techdocs/src/reader/transformers/styles/transformer.ts +++ b/plugins/techdocs/src/reader/transformers/styles/transformer.ts @@ -20,10 +20,26 @@ import { useSidebarPinState } from '@backstage/core-components'; import { Transformer } from '../transformer'; import { rules } from './rules'; +const SIDEBAR_WIDTH = 224; /** - * Sidebar pinned state to be used in computing style injections. + * Enhanced sidebar state that detects presence through CSS environment. */ -const useSidebar = () => useSidebarPinState(); +const useSidebar = () => { + const pinState = useSidebarPinState(); + + const hasSidebar = useMemo( + () => + typeof window !== 'undefined' && + Boolean(document.querySelector('[class*="BackstageSidebar"]')), + [], + ); + + return { + isPinned: pinState.isPinned, + isPresent: hasSidebar, + width: SIDEBAR_WIDTH, + }; +}; /** * Process all rules and concatenate their definitions into a single style.