Skip to content

SplitPageLayout API #2144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 30, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
313 changes: 313 additions & 0 deletions docs/content/SplitPageLayout.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
---
title: SplitPageLayout
componentId: split_page_layout
status: Draft
description: Provides structure for a split page layout, including independent scrolling for the pane and content regions. Useful for responsive list/detail patterns, when an item in the pane updates the page content on selection.
---

<Note variant="warning">Not implemented yet</Note>

## Examples

### Default

```jsx
<SplitPageLayout>
<SplitPageLayout.Header>
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Pane>
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Footer>
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

### With pane hidden on narrow viewports

```jsx
<SplitPageLayout>
<SplitPageLayout.Header>
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Pane hidden={{narrow: true}}>
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Footer>
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

### With content hidden on narrow viewports

```jsx
<SplitPageLayout>
<SplitPageLayout.Header>
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Pane>
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content hidden={{narrow: true}}>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Footer>
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

### Without dividers

```jsx
<SplitPageLayout>
<SplitPageLayout.Header divider="none">
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Pane divider="none">
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Footer divider="none">
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

### With pane on right

```jsx
<SplitPageLayout>
<SplitPageLayout.Header>
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Content>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Pane position="end">
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Footer>
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

### Without padding

```jsx
<SplitPageLayout>
<SplitPageLayout.Header padding="none">
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Pane padding="none">
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content padding="none">
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Footer padding="none">
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

### Without header or footer

```jsx
<SplitPageLayout>
<SplitPageLayout.Pane>
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
</SplitPageLayout>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yay! makes so much sense

```

### With non-sticky pane

```jsx
<SplitPageLayout>
<SplitPageLayout.Header>
<Placeholder label="Header" height={64} />
</SplitPageLayout.Header>
<SplitPageLayout.Pane sticky={false}>
<Placeholder label="Pane" height={120} />
</SplitPageLayout.Pane>
<SplitPageLayout.Content>
<Placeholder label="Content" height={240} />
</SplitPageLayout.Content>
<SplitPageLayout.Footer>
<Placeholder label="Footer" height={64} />
</SplitPageLayout.Footer>
</SplitPageLayout>
```

## Props

### SplitPageLayout

<PropsTable>
<PropsTableSxRow />
</PropsTable>

### SplitPageLayout.Header

<PropsTable>
<PropsTableRow
name="divider"
// TODO: Document ResponsiveValue
// This prop accepts a viewport range map (i.e. {regular: ..., narrow: ...}) in addition to a single value.
// The `regular` and `wide` keys of the viewport range map can be 'none' or 'line'.
// The `narrow` key of the viewport range map can be 'none' or 'line' or 'filled'.
type={`ResponsiveValue<
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResponsiveValue<> is a little cryptic. Should we explicitly write out the object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. ResponsiveValue<> doesn't explain much. The full type signature looks like this:

'none' | 'line' | { narrow?: 'none' | 'line' | 'filled'; regular?: 'none' | 'line'; wide?: 'none' | 'line' }

Do you think it'd be overwhelming to show the whole thing?

My original plan was to add a separate documentation page about responsive props that explains what ResponsiveValue<> means and link to it from here.

'none' | 'line',
'none' | 'line' | 'filled'
>`}
defaultValue="'line'"
/>
<PropsTableRow
name="hidden"
type={`ResponsiveValue<boolean>`}
defaultValue="false"
description="Whether the header is hidden."
/>
<PropsTableRow
name="padding"
type={`| 'none'
| 'normal'
| 'condensed'`}
defaultValue="'normal'"
/>
<PropsTableSxRow />
</PropsTable>

### SplitPageLayout.Content

<PropsTable>
<PropsTableRow
name="width"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be called "maxWidth" if it's the maximum width of the content area?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me. We'd need to update this in PageLayout as well. @vdepizzol @jonrohan How you feel about width -> maxWidth?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should remain as width. As a prop, it's a characteristic of the region, not a reference to the CSS attribute. Responsive components are expected to adjust on smaller viewport sizes anyway.

type={`| 'full'
| 'medium'
| 'large'
| 'xlarge'`}
defaultValue="'xlarge'"
description="The maximum width of the content region."
/>
<PropsTableRow
name="hidden"
type={`ResponsiveValue<boolean>`}
defaultValue="false"
description="Whether the content is hidden."
/>
<PropsTableRow
name="padding"
type={`| 'none'
| 'normal'
| 'condensed'`}
defaultValue="'normal'"
/>
<PropsTableSxRow />
</PropsTable>

### SplitPageLayout.Pane

<PropsTable>
<PropsTableRow
name="position"
type={`ResponsiveValue<
'start' | 'end'
>`}
defaultValue="'start'"
/>
<PropsTableRow
name="width"
type={`| 'small'
| 'medium'
| 'large'`}
defaultValue="'medium'"
description="The width of the pane."
/>
<PropsTableRow
name="divider"
type={`ResponsiveValue<
'none' | 'line',
'none' | 'line' | 'filled'
>`}
defaultValue="'line'"
/>
<PropsTableRow
name="hidden"
type={`ResponsiveValue<boolean>`}
defaultValue="false"
description="Whether the pane is hidden."
/>
<PropsTableRow
name="padding"
type={`| 'none'
| 'normal'
| 'condensed'`}
defaultValue="'normal'"
/>
<PropsTableSxRow />
</PropsTable>

### SplitPageLayout.Footer

<PropsTable>
<PropsTableRow
name="divider"
type={`ResponsiveValue<
'none' | 'line',
'none' | 'line' | 'filled'
>`}
defaultValue="'line'"
/>
<PropsTableRow
name="hidden"
type={`ResponsiveValue<boolean>`}
defaultValue="false"
description="Whether the footer is hidden."
/>
<PropsTableRow
name="padding"
type={`| 'none'
| 'normal'
| 'condensed'`}
defaultValue="'normal'"
/>
<PropsTableSxRow />
</PropsTable>

## Status

<ComponentChecklist
items={{
propsDocumented: true,
noUnnecessaryDeps: false,
adaptsToThemes: false,
adaptsToScreenSizes: false,
fullTestCoverage: false,
usedInProduction: false,
usageExamplesDocumented: false,
hasStorybookStories: false,
designReviewed: false,
a11yReviewed: false,
stableApi: false,
addressedApiFeedback: false,
hasDesignGuidelines: false,
hasFigmaComponent: false
}}
/>