-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
[core] feat: Section component #6245
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
62b5df2
Initial commit
CPerinet 4322ae2
small
CPerinet 06504ac
padded
CPerinet 230f7db
Options cleanup
CPerinet 993da84
docs
CPerinet e5b6314
Tabs
CPerinet f69863c
Tabs
CPerinet 4ca0509
Collapsible
CPerinet da02e3a
Divider
CPerinet 049db38
Divider fix
CPerinet caa8de7
Clean up code, fix lint, skip test coverage
adidahiya 349d5ef
Use Collapse component, fix tabs height
adidahiya fee9bc4
remove tabs support
adidahiya b41a749
Support collapseProps
adidahiya 3428c32
Rename SectionContent -> SectionPanel
adidahiya b235e35
use EditableText to make rightElement functional
adidahiya 8708091
various refactor fixes
adidahiya 4401d2b
Remove unused Classes.COLLAPSED
adidahiya 9b8a94a
self-review fixes
adidahiya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
@use "sass:math"; | ||
@import "../../common/variables"; | ||
|
||
$section-min-height: $pt-grid-size * 5 !default; | ||
$section-vertical-padding: $pt-grid-size !default; | ||
$section-horizontal-padding: $pt-grid-size * 2 !default; | ||
$section-panel-padding: $pt-grid-size * 2 !default; | ||
|
||
$section-compact-min-height: $pt-grid-size * 4 !default; | ||
$section-compact-vertical-padding: 7px !default; | ||
$section-compact-horizontal-padding: 15px !default; | ||
$section-compact-panel-padding: $pt-grid-size * 1.5 !default; | ||
|
||
.#{$ns}-section { | ||
overflow: hidden; | ||
padding: 0; | ||
width: 100%; | ||
|
||
&-header { | ||
align-items: center; | ||
border-bottom: 1px solid $pt-divider-black; | ||
display: flex; | ||
gap: $pt-grid-size * 2; | ||
justify-content: space-between; | ||
min-height: $section-min-height; | ||
padding: 0 $section-horizontal-padding; | ||
position: relative; | ||
width: 100%; | ||
|
||
&.#{$ns}-dark, | ||
.#{$ns}-dark & { | ||
border-color: $pt-dark-divider-white; | ||
} | ||
|
||
&-left { | ||
align-items: center; | ||
display: flex; | ||
gap: $pt-grid-size; | ||
padding: $section-vertical-padding 0; | ||
} | ||
|
||
&-title { | ||
margin-bottom: 0; | ||
} | ||
|
||
&-sub-title { | ||
margin-top: 2px; | ||
} | ||
|
||
&-right { | ||
align-items: center; | ||
display: flex; | ||
gap: $pt-grid-size; | ||
margin-left: auto; | ||
} | ||
|
||
&-divider { | ||
align-self: stretch; | ||
margin: $pt-grid-size * 1.5 0; | ||
} | ||
|
||
&.#{$ns}-interactive { | ||
cursor: pointer; | ||
|
||
&:hover, | ||
&:active { | ||
background: $light-gray5; | ||
|
||
&.#{$ns}-dark, | ||
.#{$ns}-dark & { | ||
background: $dark-gray4; | ||
} | ||
} | ||
} | ||
} | ||
|
||
&-panel { | ||
&.#{$ns}-padded { | ||
padding: $section-panel-padding; | ||
} | ||
|
||
&:not(:last-child) { | ||
border-bottom: 1px solid $pt-divider-black; | ||
|
||
&.#{$ns}-dark, | ||
.#{$ns}-dark & { | ||
border-color: $pt-dark-divider-white; | ||
} | ||
} | ||
} | ||
|
||
&.#{$ns}-section-collapsed { | ||
.#{$ns}-section-header { | ||
border: none; | ||
} | ||
} | ||
|
||
&.#{$ns}-compact { | ||
.#{$ns}-section-header { | ||
min-height: $section-compact-min-height; | ||
padding: 0 $section-compact-horizontal-padding; | ||
|
||
&-left { | ||
padding: $section-compact-vertical-padding 0; | ||
} | ||
} | ||
|
||
.#{$ns}-section-panel.#{$ns}-padded { | ||
padding: $section-compact-panel-padding; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
@# Section | ||
|
||
The __Section__ component can be used to contain, structure, and create hierarchy for information in your UI. It makes use of some concepts from other more atomic Blueprint components: | ||
|
||
- The overall appearance looks like a [__Card__](#core/components/card) | ||
- Contents may be collapsible like the [__Collapse__](#core/components/collapse) component | ||
|
||
@reactExample SectionExample | ||
|
||
@## Props interface | ||
|
||
@interface SectionProps | ||
|
||
@## Section panel | ||
|
||
Multiple __SectionPanel__ child components can be added under one __Section__, they will be stacked vertically. This layout can be used to further group information. | ||
|
||
```tsx | ||
<Section> | ||
<SectionPanel>{/* ... */}</SectionPanel> | ||
<SectionPanel>{/* ... */}</SectionPanel> | ||
</Section> | ||
``` | ||
|
||
@interface SectionPanelProps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* Copyright 2023 Palantir Technologies, Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import classNames from "classnames"; | ||
import * as React from "react"; | ||
|
||
import { ChevronDown, ChevronUp, IconName } from "@blueprintjs/icons"; | ||
|
||
import { Classes, Elevation } from "../../common"; | ||
import { DISPLAYNAME_PREFIX, HTMLDivProps, MaybeElement, Props } from "../../common/props"; | ||
import { Card } from "../card/card"; | ||
import { Collapse, CollapseProps } from "../collapse/collapse"; | ||
import { H6 } from "../html/html"; | ||
import { Icon } from "../icon/icon"; | ||
|
||
export interface SectionProps extends Props, Omit<HTMLDivProps, "title">, React.RefAttributes<HTMLDivElement> { | ||
/** | ||
* Whether this section's contents should be collapsible. | ||
* | ||
* @default false | ||
*/ | ||
collapsible?: boolean; | ||
|
||
/** | ||
* Subset of props to forward to the underlying {@link Collapse} component, with the addition of a | ||
* `defaultIsOpen` option which sets the default open state of the component. | ||
* | ||
* This prop has no effect if `collapsible={false}`. | ||
*/ | ||
collapseProps?: Pick<CollapseProps, "className" | "keepChildrenMounted" | "transitionDuration"> & { | ||
defaultIsOpen?: boolean; | ||
}; | ||
|
||
/** | ||
* Whether this section should use compact styles. | ||
* | ||
* @default false | ||
*/ | ||
compact?: boolean; | ||
|
||
/** | ||
* Name of a Blueprint UI icon (or an icon element) to render in the section's header. | ||
* Note that the header will only be rendered if `title` is provided. | ||
*/ | ||
icon?: IconName | MaybeElement; | ||
|
||
/** | ||
* Element to render on the right side of the section header. | ||
*/ | ||
rightElement?: JSX.Element; | ||
|
||
/** | ||
* Sub-title of the section. | ||
* Note that the header will only be rendered if `title` is provided. | ||
*/ | ||
subtitle?: JSX.Element | string; | ||
|
||
/** | ||
* Title of the section. | ||
* Note that the header will only be rendered if `title` is provided. | ||
*/ | ||
title?: JSX.Element | string; | ||
} | ||
|
||
/** | ||
* Section component. | ||
* | ||
* @see https://blueprintjs.com/docs/#core/components/section | ||
*/ | ||
export const Section: React.FC<SectionProps> = React.forwardRef((props, ref) => { | ||
const { | ||
children, | ||
className, | ||
collapseProps, | ||
collapsible, | ||
compact, | ||
icon, | ||
rightElement, | ||
subtitle, | ||
title, | ||
...cardProps | ||
} = props; | ||
const [isCollapsed, setIsCollapsed] = React.useState<boolean>(collapseProps?.defaultIsOpen ?? false); | ||
const toggleIsCollapsed = React.useCallback(() => setIsCollapsed(!isCollapsed), [isCollapsed]); | ||
|
||
const isHeaderLeftContainerVisible = title != null || icon != null || subtitle != null; | ||
const isHeaderRightContainerVisible = rightElement != null || collapsible; | ||
|
||
return ( | ||
<Card | ||
elevation={Elevation.ZERO} | ||
className={classNames(className, Classes.SECTION, { | ||
[Classes.COMPACT]: compact, | ||
[Classes.SECTION_COLLAPSED]: collapsible && isCollapsed, | ||
})} | ||
ref={ref} | ||
{...cardProps} | ||
> | ||
<div | ||
role={collapsible ? "button" : undefined} | ||
aria-pressed={collapsible ? isCollapsed : undefined} | ||
className={classNames(Classes.SECTION_HEADER, { | ||
[Classes.INTERACTIVE]: collapsible, | ||
})} | ||
onClick={collapsible != null ? toggleIsCollapsed : undefined} | ||
> | ||
{isHeaderLeftContainerVisible && ( | ||
<> | ||
<div className={Classes.SECTION_HEADER_LEFT}> | ||
{title && icon && ( | ||
<Icon icon={icon} aria-hidden={true} tabIndex={-1} className={Classes.TEXT_MUTED} /> | ||
)} | ||
|
||
<div> | ||
{title && <H6 className={Classes.SECTION_HEADER_TITLE}>{title}</H6>} | ||
{title && subtitle && ( | ||
<div className={classNames(Classes.TEXT_MUTED, Classes.SECTION_HEADER_SUB_TITLE)}> | ||
{subtitle} | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
</> | ||
)} | ||
|
||
{isHeaderRightContainerVisible && ( | ||
<div className={Classes.SECTION_HEADER_RIGHT}> | ||
{rightElement} | ||
{collapsible && | ||
(isCollapsed ? ( | ||
<ChevronDown className={Classes.TEXT_MUTED} /> | ||
) : ( | ||
<ChevronUp className={Classes.TEXT_MUTED} /> | ||
))} | ||
</div> | ||
)} | ||
</div> | ||
|
||
{collapsible ? ( | ||
<Collapse {...collapseProps} isOpen={!isCollapsed}> | ||
{children} | ||
</Collapse> | ||
) : ( | ||
children | ||
)} | ||
</Card> | ||
); | ||
}); | ||
Section.defaultProps = { | ||
compact: false, | ||
}; | ||
Section.displayName = `${DISPLAYNAME_PREFIX}.Section`; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to add a "section"-namespaced "collapsed" class name for now rather than a
.bp5-collapsed
name.