Skip to content

Commit

Permalink
Add optional footer prop to SelectPanel (#4353)
Browse files Browse the repository at this point in the history
* Spike on adding a footer

* Update changelog

* Storybook update

* Update styling

* move margin to internal padding space

* Update bright-foxes-hunt.md

* Update bright-foxes-hunt.md

---------

Co-authored-by: Pavithra Kodmad <pksjce@github.com>
Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com>
  • Loading branch information
3 people committed Mar 11, 2024
1 parent 10653a2 commit 2c0086e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-foxes-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

SelectPanel: Added `footer` prop that renders a sticky footer at the bottom of the item list.
74 changes: 74 additions & 0 deletions packages/react/src/SelectPanel/SelectPanel.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,80 @@ export const ExternalAnchorStory = () => {
}
ExternalAnchorStory.storyName = 'With External Anchor'

export const WithFooterStory = () => {
const [selected, setSelected] = React.useState<ItemInput | undefined>(items[0])
const [filter, setFilter] = React.useState('')
const filteredItems = items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase()))
const [open, setOpen] = useState(false)
const buttonRef = useRef<HTMLButtonElement>(null)

return (
<>
<h1>Select Panel With Footer</h1>
<SelectPanel
renderAnchor={({children, 'aria-labelledby': ariaLabelledBy, ...anchorProps}) => (
<Button trailingAction={TriangleDownIcon} aria-labelledby={` ${ariaLabelledBy}`} {...anchorProps}>
{children ?? 'Select Labels'}
</Button>
)}
anchorRef={buttonRef}
placeholderText="Filter Labels"
open={open}
onOpenChange={setOpen}
items={filteredItems}
selected={selected}
onSelectedChange={setSelected}
onFilterChange={setFilter}
showItemDividers={true}
overlayProps={{width: 'small', height: 'medium'}}
footer={
<Button size="small" block>
Edit labels
</Button>
}
/>
</>
)
}
WithFooterStory.storyName = 'With Footer'

export const MultiSelectWithFooterStory = () => {
const [selected, setSelected] = React.useState<ItemInput[]>([items[0], items[1]])
const [filter, setFilter] = React.useState('')
const filteredItems = items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase()))
const [open, setOpen] = useState(false)
const buttonRef = useRef<HTMLButtonElement>(null)

return (
<>
<h1>Multi Select Panel With Footer</h1>
<SelectPanel
renderAnchor={({children, 'aria-labelledby': ariaLabelledBy, ...anchorProps}) => (
<Button trailingAction={TriangleDownIcon} aria-labelledby={` ${ariaLabelledBy}`} {...anchorProps}>
{children ?? 'Select Labels'}
</Button>
)}
anchorRef={buttonRef}
placeholderText="Filter Labels"
open={open}
onOpenChange={setOpen}
items={filteredItems}
selected={selected}
onSelectedChange={setSelected}
onFilterChange={setFilter}
showItemDividers={true}
overlayProps={{width: 'small', height: 'medium'}}
footer={
<Button size="small" block>
Edit labels
</Button>
}
/>
</>
)
}
MultiSelectWithFooterStory.storyName = 'With Footer (Multi Select)'

export const SelectPanelHeightInitialWithOverflowingItemsStory = () => {
const [selected, setSelected] = React.useState<ItemInput | undefined>(items[0])
const [filter, setFilter] = React.useState('')
Expand Down
14 changes: 14 additions & 0 deletions packages/react/src/SelectPanel/SelectPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ interface SelectPanelBaseProps {
// TODO: Make `inputLabel` required in next major version
inputLabel?: string
overlayProps?: Partial<OverlayProps>
footer?: string | React.ReactElement
}

export type SelectPanelProps = SelectPanelBaseProps &
Expand Down Expand Up @@ -81,6 +82,7 @@ export function SelectPanel({
filterValue: externalFilterValue,
onFilterChange: externalOnFilterChange,
items,
footer,
textInputProps,
overlayProps,
sx,
Expand Down Expand Up @@ -225,6 +227,18 @@ export function SelectPanel({
// than the Overlay (which would break scrolling the items)
sx={{...sx, height: 'inherit', maxHeight: 'inherit'}}
/>
{footer && (
<Box
sx={{
display: 'flex',
borderTop: '1px solid',
borderColor: 'border.default',
padding: 2,
}}
>
{footer}
</Box>
)}
</Box>
</AnchoredOverlay>
</LiveRegion>
Expand Down

0 comments on commit 2c0086e

Please sign in to comment.