From 5411a5190a0a3c13c3e6d2e834674e7619e2c8de Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 16 Nov 2023 11:18:10 -0700 Subject: [PATCH] Hide "On this page" on narrow viewports - Remove collapsed functionality from InPageTOC - Dramatically simplify DocsScreen layout - No longer need to shift InPageTOC from between title & content to right rail --- src/components/basics/InPageTOC.stories.tsx | 16 --- src/components/basics/InPageTOC.tsx | 68 +--------- .../screens/DocsScreen/DocsScreen.stories.tsx | 4 +- .../screens/DocsScreen/DocsScreen.tsx | 123 +++++++++--------- 4 files changed, 69 insertions(+), 142 deletions(-) diff --git a/src/components/basics/InPageTOC.stories.tsx b/src/components/basics/InPageTOC.stories.tsx index e28a9b7c..494d5e8d 100644 --- a/src/components/basics/InPageTOC.stories.tsx +++ b/src/components/basics/InPageTOC.stories.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; -import { userEvent, within } from '@storybook/testing-library'; import { InPageTOC } from './InPageTOC'; const mockTOCItems = [ @@ -67,18 +66,3 @@ export default meta; const Template = (args) => ; export const Basic = Template.bind({}); - -export const Collapsed = Template.bind({}); -Collapsed.args = { - collapsed: true, -}; - -export const Open = Template.bind({}); -Open.args = Collapsed.args; -Open.play = async ({ canvasElement }) => { - const canvas = within(canvasElement); - - const summary = canvas.getByText('On this page'); - - await userEvent.click(summary); -}; diff --git a/src/components/basics/InPageTOC.tsx b/src/components/basics/InPageTOC.tsx index 74c5a1a7..4b18c01f 100644 --- a/src/components/basics/InPageTOC.tsx +++ b/src/components/basics/InPageTOC.tsx @@ -1,50 +1,11 @@ import * as React from 'react'; import { styled } from '@storybook/theming'; -import { ChevronSmallDownIcon } from '@storybook/icons'; -import { color, fontFamily, spacing, Text } from '@chromaui/tetra'; +import { color, spacing, Text } from '@chromaui/tetra'; const Heading = styled((props) => )` margin-bottom: ${spacing[3]}; `; -const Summary = styled.summary` - border: 0; - border-radius: ${spacing[1]}; - cursor: pointer; - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0 0.5rem; - margin-left: -0.5rem; - background: transparent; - color: ${color.slate500}; - height: 1.75rem; - font-size: 0.75rem; - font-weight: 600; - font-family: ${fontFamily.sans}; - gap: 0.375rem; - transition: all 0.16s ease-in-out; - - &:hover { - background: rgba(255, 255, 255, 0.1); - } - - [open] > & { - margin-bottom: ${spacing[3]}; - - & > .CaretDown { - transform: rotate(-180deg) translateY(0px); - } - } -`; - -const CaretDown = styled.div` - position: relative; - width: 14px; - height: 14px; - transition: transform 250ms ease; -`; - const List = styled.ol` list-style: none; margin: 0; @@ -77,12 +38,12 @@ type Item = { }; type InPageTOCProps = { - collapsed?: boolean; items: Item[]; }; -export const InPageTOC = ({ collapsed, items }: InPageTOCProps) => { - const toc = ( +export const InPageTOC = ({ items }: InPageTOCProps) => ( + <> + On this page {items.map((h2Item) => ( @@ -108,22 +69,5 @@ export const InPageTOC = ({ collapsed, items }: InPageTOCProps) => { ))} - ); - - return collapsed ? ( -
- - On this page - - - - - {toc} -
- ) : ( - <> - On this page - {toc} - - ); -}; + +); diff --git a/src/components/screens/DocsScreen/DocsScreen.stories.tsx b/src/components/screens/DocsScreen/DocsScreen.stories.tsx index 8edb4d66..7dd083de 100644 --- a/src/components/screens/DocsScreen/DocsScreen.stories.tsx +++ b/src/components/screens/DocsScreen/DocsScreen.stories.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { styled } from '@storybook/theming'; -import DocsScreen from './DocsScreen'; +import DocsScreen, { IS_2_COL_BREAKPOINT } from './DocsScreen'; import compiledMDX from '../../../../.storybook/compiled-mdx'; import { pageContext } from '../../layout/DocsLayout.stories'; @@ -104,6 +104,6 @@ export const WithTableOfContents = () => ( ); WithTableOfContents.parameters = { chromatic: { - viewports: [400, 1400], + viewports: [400, IS_2_COL_BREAKPOINT], }, }; diff --git a/src/components/screens/DocsScreen/DocsScreen.tsx b/src/components/screens/DocsScreen/DocsScreen.tsx index 8ac981a6..8a4c81da 100644 --- a/src/components/screens/DocsScreen/DocsScreen.tsx +++ b/src/components/screens/DocsScreen/DocsScreen.tsx @@ -32,15 +32,24 @@ const { color: dsColor, spacing: dsSpacing, typography } = styles; const MIN_HEADINGS_COUNT_FOR_TOC = 3; /** - * TODO: This breakpoint is a compromise: - * - Nav from `components-marketing` and `Container` from `tetra` both apply a bigger margin at - * wider viewports, which results in a too narrow overall available width - * - That worked fine for a 1-col content layout, but does not work for a 2-col layout + * Note: This breakpoint should be revisited. + * - It provides a minimum width of 600px for the content area. + * - The rest of the SB properties (and the prior design of docs) use a 2-col width. To maintain a + * legible line length, the left/right margins of the page layout (codified in Nav from + * `components-marketing` and Container from `tetra`) increase at 1200px. But that doesn't leave + * much available width for a 3-column layout, resulting in this rather wide breakpoint. + * - To reduce this breakpoint (making the InPageTOC visible for more users), we'd need to either: + * a. Change the page layout for _just_ the docs, resulting in a different layout from the other + * SB properties + * b. Change the page layout for all SB properties, resulting in longer line lengths or necessary + * layout adjustments in some places */ -const IS_2_COL_BREAKPOINT = 1400; +export const IS_2_COL_BREAKPOINT = 1548; + +const RIGHT_RAIL_WIDTH = '220px'; // Magic number to account for PageLayout header height -const IN_PAGE_TOC_TOP_OFFSET = 112; +const RIGHT_RAIL_TOP_OFFSET = '112px'; const Root = styled('div', { shouldForwardProp: (prop) => prop !== 'hasRightRail', @@ -48,43 +57,34 @@ const Root = styled('div', { ${({ hasRightRail }) => hasRightRail && css` - @media (min-width: ${IS_2_COL_BREAKPOINT}px) { - display: grid; - grid-template-columns: 1fr 240px; - grid-template-rows: repeat(2, min-content); - grid-column-gap: ${spacing[8]}; - } + display: flex; + flex-direction: row-reverse; + gap: ${spacing[8]}; `} `; const Header = styled.div` - grid-area: 1 / 1 / 2 / 2; margin-bottom: ${spacing[8]}; `; const RightRail = styled.div` + flex: 0 0 ${RIGHT_RAIL_WIDTH}; margin-bottom: ${spacing[8]}; - grid-area: 1 / 2 / 3 / 3; - - @media (min-width: ${IS_2_COL_BREAKPOINT}px) { - position: relative; - top: -48px; - } + position: relative; + top: -48px; `; const RightRailSticky = styled.div` position: sticky; - top: ${IN_PAGE_TOC_TOP_OFFSET}px; + top: ${RIGHT_RAIL_TOP_OFFSET}; `; const RightRailRoot = styled(ScrollArea.Root)` position: relative; - width: 240px; + width: ${RIGHT_RAIL_WIDTH}; margin: 0; padding-bottom: 0; - padding-right: 20px; - margin-right: 20px; - height: calc(100vh - ${IN_PAGE_TOC_TOP_OFFSET}px); + height: calc(100vh - ${RIGHT_RAIL_TOP_OFFSET}); `; const RightRailViewport = styled(ScrollArea.Viewport)` @@ -118,13 +118,12 @@ const RightRailThumb = styled(ScrollArea.Thumb)` `; const Content = styled.div` - grid-area: 2 / 1 / 3 / 2; + flex: 1 1 auto; min-width: 0; `; const MDWrapper = styled.main` ${mdFormatting} - flex: 1; `; const Title = styled.h1` @@ -215,6 +214,8 @@ function DocsScreen({ data, pageContext, location }) { const hasHeadings = pageTocItems.flatMap((item) => (item.items ? [item, ...item.items] : item)).length > MIN_HEADINGS_COUNT_FOR_TOC; + const [is2Col] = useMediaQuery(`(min-width: ${IS_2_COL_BREAKPOINT}px)`); + const hasRightRail = is2Col && hasHeadings; const { allRenderers, @@ -232,8 +233,6 @@ function DocsScreen({ data, pageContext, location }) { renderer: [renderer], } = useDocsContext(); - const [is2Col] = useMediaQuery(`(min-width: ${IS_2_COL_BREAKPOINT}px)`); - const CodeSnippetsWithState = useMemo(() => { return (props) => ( @@ -316,44 +315,44 @@ function DocsScreen({ data, pageContext, location }) { return ( <> - -
- {isInstallPage ? `${title} for ${stylizeRenderer(renderer)}` : title} - - {unsupported && ( - - This feature is not supported in {stylizeRenderer(renderer)} yet. Help the open source - community by contributing a PR. - {featureSupportItem && ( - <> - {' '} - - View feature coverage by renderer - - - )} - - )} -
- {hasHeadings && ( + + {hasRightRail && ( - {is2Col ? ( - - - - - - - - - - - ) : ( - - )} + + + + + + + + + + )} +
+ {isInstallPage ? `${title} for ${stylizeRenderer(renderer)}` : title} + + {unsupported && ( + + This feature is not supported in {stylizeRenderer(renderer)} yet. Help the open + source community by contributing a PR. + {featureSupportItem && ( + <> + {' '} + + View feature coverage by renderer + + + )} + + )} +
+