Skip to content

Commit

Permalink
SelectPanel2: Fix height for fit-content in Safari (#4170)
Browse files Browse the repository at this point in the history
* fix small overlay

* default height to large

* add story for short panel from settings

* update changeset

* Update selectpanel-fix-height.md

* add example with changing height
  • Loading branch information
siddharthkp authored Jan 23, 2024
1 parent 996475f commit 18d1609
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .changeset/selectpanel-fix-height.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

experimental/SelectPanel: Fix height for `fit-content` in Safari
5 changes: 0 additions & 5 deletions .changeset/warm-actors-jam.md

This file was deleted.

1 change: 1 addition & 0 deletions src/Overlay/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const heightMap = {
xlarge: '600px',
auto: 'auto',
initial: 'auto', // Passing 'initial' initially applies 'auto'
'fit-content': 'fit-content',
}

const widthMap = {
Expand Down
10 changes: 3 additions & 7 deletions src/drafts/SelectPanel2/SelectPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ const Panel: React.FC<SelectPanelProps> = ({
return (
<>
{Anchor}
{/* @ts-ignore TODO: StyledOverlay does not like height:fit-content */}

<StyledOverlay
as="dialog"
ref={dialogRef}
Expand All @@ -234,6 +234,7 @@ const Panel: React.FC<SelectPanelProps> = ({
// reset dialog default styles
border: 'none',
padding: 0,
'&[open]': {display: 'flex'}, // to fit children

...(variant === 'anchored' ? {margin: 0, top: position?.top, left: position?.left} : {}),
'::backdrop': {backgroundColor: variant === 'anchored' ? 'transparent' : 'primer.canvas.backdrop'},
Expand Down Expand Up @@ -269,12 +270,7 @@ const Panel: React.FC<SelectPanelProps> = ({
as="form"
method="dialog"
onSubmit={onInternalSubmit}
sx={{
display: 'flex',
flexDirection: 'column',
height: 'initial',
minHeight: '100%',
}}
sx={{display: 'flex', flexDirection: 'column', width: '100%'}}
>
{slots.header ?? /* render default header as fallback */ <SelectPanelHeader />}

Expand Down
69 changes: 36 additions & 33 deletions src/drafts/SelectPanel2/stories/SelectPanel.examples.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {SelectPanel} from '../SelectPanel'
import {ActionList, ActionMenu, Avatar, Box, Button} from '../../../index'
import {ActionList, ActionMenu, Avatar, Box, Button, Text} from '../../../index'
import {ArrowRightIcon, EyeIcon, GitBranchIcon, TriangleDownIcon, GearIcon} from '@primer/octicons-react'
import data from './mock-data'

Expand Down Expand Up @@ -582,54 +582,57 @@ export const WithFilterButtons = () => {
)
}

export const CustomHeight = () => {
const initialSelectedLabels = data.issue.labelIds // mock initial state: has selected labels
const [selectedLabelIds, setSelectedLabelIds] = React.useState<string[]>(initialSelectedLabels)

/* Selection */
const onLabelSelect = (labelId: string) => {
if (!selectedLabelIds.includes(labelId)) setSelectedLabelIds([...selectedLabelIds, labelId])
else setSelectedLabelIds(selectedLabelIds.filter(id => id !== labelId))
}
export const ShortSelectPanel = () => {
const [channels, setChannels] = React.useState({GitHub: false, Email: false})
const [onlyFailures, setOnlyFailures] = React.useState(false)

const onSubmit = () => {
data.issue.labelIds = selectedLabelIds // pretending to persist changes

// eslint-disable-next-line no-console
console.log('form submitted')
}

const sortingFn = (itemA: {id: string}, itemB: {id: string}) => {
const initialSelectedIds = data.issue.labelIds
if (initialSelectedIds.includes(itemA.id) && initialSelectedIds.includes(itemB.id)) return 1
else if (initialSelectedIds.includes(itemA.id)) return -1
else if (initialSelectedIds.includes(itemB.id)) return 1
else return 1
const toggleChannel = (channel: keyof typeof channels) => {
setChannels({...channels, [channel]: !channels[channel]})
}

const itemsToShow = data.labels.sort(sortingFn)
const channelsEnabled = channels.GitHub || channels.Email

return (
<>
<h1>Custom height SelectPanel</h1>
<h1>Short SelectPanel</h1>
<p>
Uses <code>height: fit-content</code> to display the full height of the dialog
Use <code>height=fit-content</code> to match height of contents
</p>
<SelectPanel title="Select labels" onSubmit={onSubmit} height="fit-content">
<SelectPanel.Button>Assign label</SelectPanel.Button>
<SelectPanel title="Select notification channels" height="fit-content" onSubmit={onSubmit}>
<SelectPanel.Button>
<Text sx={{color: 'fg.muted'}}>Notify me:</Text>{' '}
{Object.keys(channels)
.filter(channel => channels[channel as keyof typeof channels])
.join(', ') || 'Never'}
{onlyFailures && channelsEnabled && ' (Failed workflows only)'}
</SelectPanel.Button>

<ActionList>
{itemsToShow.slice(0, 10).map(label => (
<ActionList.Item
key={label.id}
onSelect={() => onLabelSelect(label.id)}
selected={selectedLabelIds.includes(label.id)}
>
<ActionList.LeadingVisual>{getCircle(label.color)}</ActionList.LeadingVisual>
{label.name}
<ActionList.Description variant="block">{label.description}</ActionList.Description>
<ActionList.Item selected={channels.GitHub} onSelect={() => toggleChannel('GitHub')}>
On GitHub
</ActionList.Item>
<ActionList.Item selected={channels.Email} onSelect={() => toggleChannel('Email')}>
Email
</ActionList.Item>
<Box
role="none"
sx={{
transition: 'max-height 100ms ease-out, opacity 100ms ease-out',
opacity: channelsEnabled ? 1 : 0,
maxHeight: channelsEnabled ? '100px' : 0,
overflow: channelsEnabled ? 'visible' : 'hidden',
}}
>
<ActionList.Divider />
<ActionList.Item selected={onlyFailures} onSelect={() => setOnlyFailures(!onlyFailures)}>
Only notify for failed workflows
</ActionList.Item>
))}
</Box>
</ActionList>
<SelectPanel.Footer />
</SelectPanel>
Expand Down

0 comments on commit 18d1609

Please sign in to comment.