diff --git a/src/layouts/sidebar-layout/index.tsx b/src/layouts/sidebar-layout/index.tsx new file mode 100644 index 0000000000..9244573dbf --- /dev/null +++ b/src/layouts/sidebar-layout/index.tsx @@ -0,0 +1,44 @@ +import { PropsWithChildren, ReactNode } from 'react' +// Layout +import BaseLayout from 'layouts/base-layout' +// Styles +import s from './sidebar-layout.module.css' + +/** + * Renders a sidebar area alongside a main content area. + * + * The sidebar area is layed out as a sticky column on large viewports. + * When very tall content is provided, the sidebar area will scroll vertically. + * + * The sidebar area is completely hidden on mobile viewports. + * Consumers should ensure that equivalent navigational elements + * are provided through the `mobileMenuSlot` prop. + * + * Note: this layout could _potentially_ be of use in `SidebarSidecarLayout`. + * For context, this layout was created after `SidebarSidecarLayout`, with the + * initial intent of making it easier to build a new OpenAPI docs view. + * It will likely make sense to consolidate somewhat duplicate layout logic between + * this component and `SidebarSidecarLayout`, but this did not feel like it + * was within the scope of the OpenAPI docs view work. + * Task: + * https://app.asana.com/0/1202097197789424/1205088749290838/f + */ +function SidebarLayout({ + children, + sidebarSlot, + mobileMenuSlot, +}: PropsWithChildren<{ + mobileMenuSlot: ReactNode + sidebarSlot: ReactNode +}>) { + return ( + +
+
{sidebarSlot}
+
{children}
+
+
+ ) +} + +export default SidebarLayout diff --git a/src/layouts/sidebar-layout/sidebar-layout.module.css b/src/layouts/sidebar-layout/sidebar-layout.module.css new file mode 100644 index 0000000000..f146b2d53e --- /dev/null +++ b/src/layouts/sidebar-layout/sidebar-layout.module.css @@ -0,0 +1,35 @@ +.root { + display: flex; + + /* Grow to fill the vertical space that BaseLayout creates */ + flex-grow: 1; + gap: 48px; + + @media (min-width: 1440px) { + gap: 64px; + } +} + +.sidebarArea { + /* Note that --navigation-header-height is set by BaseLayout styles */ + background-color: var(--token-color-surface-primary); + box-shadow: var(--token-surface-base-box-shadow); + display: none; + + /* Even if content is long, area shoul dbe fully within the viewport. + For shorter content, we don't need the height to be tall. */ + max-height: calc(100vh - var(--navigation-header-height)); + overflow: auto; + padding: 24px 24px 100px 24px; + position: sticky; + top: var(--navigation-header-height); + width: 312px; + + @media (--dev-dot-hide-mobile-menu) { + display: block; + } +} + +.mainArea { + flex: 1 1 0; +} diff --git a/src/views/open-api-docs-view/index.tsx b/src/views/open-api-docs-view/index.tsx index 0eb9417c4a..7e49aa281f 100644 --- a/src/views/open-api-docs-view/index.tsx +++ b/src/views/open-api-docs-view/index.tsx @@ -1,3 +1,8 @@ +// Layout +import SidebarLayout from 'layouts/sidebar-layout' +// Local +import MobileMenuLevelsGeneric from 'components/mobile-menu-levels-generic' +// Types import type { OpenApiDocsViewProps } from './types' /** @@ -5,12 +10,21 @@ import type { OpenApiDocsViewProps } from './types' */ function OpenApiDocsView(props: OpenApiDocsViewProps) { return ( -
-

OpenApiDocsView Placeholder

-
-				{JSON.stringify(props, null, 2)}
-			
-
+ + PLACEHOLDER for sidebar contents + + } + mobileMenuSlot={} + > +
+

OpenApiDocsView Placeholder

+
+					{JSON.stringify(props, null, 2)}
+				
+
+
) }