Skip to content

Llastflowers/5118/select panel unhide footer #6170

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 22 commits into from
Jun 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9af7d8a
sync primer/react versions
llastflowers Jun 2, 2025
68e1285
keep footer from disappearing behind keyboard on SelectPanel
llastflowers Jun 5, 2025
de21ef2
remove a line of CSS that made footer button slightly off-center
llastflowers Jun 5, 2025
0dac1fe
Merge branch 'main' into llastflowers/5118/SelectPanel-pin-footer
llastflowers Jun 5, 2025
ebb7752
oops, fixing a couple lines of css I didn't mean to change
llastflowers Jun 5, 2025
d22396b
Create dull-pots-appear.md
llastflowers Jun 5, 2025
4293458
make CI lint checks happy
llastflowers Jun 5, 2025
9a05674
fix code comments
llastflowers Jun 5, 2025
deb73f1
test(vrt): update snapshots
llastflowers Jun 5, 2025
2b592ac
Update packages/react/src/SelectPanel/SelectPanel.tsx
llastflowers Jun 5, 2025
bd5aff8
Update dull-pots-appear.md
llastflowers Jun 5, 2025
082b06b
refactoring based on PR comments
llastflowers Jun 6, 2025
9413683
refactoring based on PR comments
llastflowers Jun 6, 2025
c4a17a7
small tweak suggested by copilot adapted to work with other new code …
llastflowers Jun 6, 2025
25e1641
incorporating copilot suggested change to prevent excessive re-renders
llastflowers Jun 6, 2025
88346dd
Update packages/react/src/SelectPanel/SelectPanel.tsx
llastflowers Jun 6, 2025
f6ffe14
combining useEffects per copilot suggestion
llastflowers Jun 6, 2025
5852e52
check viewport scale and don't reposition anything if scale changes; …
llastflowers Jun 9, 2025
305fed3
add check that SelectPanel is open before running keyboard/resizing-r…
llastflowers Jun 9, 2025
22e9b8a
ignore eslint redundancy check in favor of satisfying typescript requ…
llastflowers Jun 9, 2025
8bf07a2
also check for isNarrowScreenSize in new useEffect
llastflowers Jun 11, 2025
daba652
Merge branch 'main' into llastflowers/5118/SelectPanel-pin-footer
primer[bot] Jun 11, 2025
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
5 changes: 5 additions & 0 deletions .changeset/dull-pots-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Update SelectPanel so that content isn't hidden behind mobile keyboard
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion packages/react/src/SelectPanel/SelectPanel.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@
display: none;
align-items: center;
padding: var(--base-size-8);
gap: var(--stack-gap-condensed);
Copy link
Member

Choose a reason for hiding this comment

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

@hectahertz tagging you since I know you worked on a lot of these, any idea why/if this is needed or are we safe to remove? 👀

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's a leftover from a previous implementation; if the snapshots look fine I can't think of any issues with removing it!

justify-content: center;

&:where([data-display-footer='always']) {
Expand Down
55 changes: 53 additions & 2 deletions packages/react/src/SelectPanel/SelectPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ const doesItemsIncludeItem = (items: ItemInput[], item: ItemInput) => {
return items.some(i => areItemsEqual(i, item))
}

const defaultRendorAnchor: NonNullable<SelectPanelProps['renderAnchor']> = props => {
const defaultRenderAnchor: NonNullable<SelectPanelProps['renderAnchor']> = props => {
const {children, ...rest} = props
return (
<Button trailingAction={TriangleDownIcon} {...rest}>
Expand All @@ -153,7 +153,7 @@ const defaultRendorAnchor: NonNullable<SelectPanelProps['renderAnchor']> = props
function Panel({
open,
onOpenChange,
renderAnchor = defaultRendorAnchor,
renderAnchor = defaultRenderAnchor,
anchorRef: externalAnchorRef,
placeholder,
placeholderText = 'Filter items',
Expand Down Expand Up @@ -201,6 +201,11 @@ function Panel({
const [selectedOnSort, setSelectedOnSort] = useState<ItemInput[]>([])
const [prevItems, setPrevItems] = useState<ItemInput[]>([])
const [prevOpen, setPrevOpen] = useState(open)
const initialHeightRef = useRef(0)
const initialScaleRef = useRef(1)
const [isKeyboardVisible, setIsKeyboardVisible] = useState(false)
const [availablePanelHeight, setAvailablePanelHeight] = useState<number | undefined>(undefined)
const KEYBOARD_VISIBILITY_THRESHOLD = 10

const usingModernActionList = useFeatureFlag('primer_react_select_panel_with_modern_action_list')
const featureFlagFullScreenOnNarrow = useFeatureFlag('primer_react_select_panel_fullscreen_on_narrow')
Expand Down Expand Up @@ -379,6 +384,46 @@ function Panel({
}
}, [open, dataLoadedOnce, onFilterChange, filterValue, items, loadingManagedExternally, listContainerElement])

useEffect(() => {
if (!window.visualViewport || !open || !isNarrowScreenSize) {
return
}

initialHeightRef.current = window.visualViewport.height
initialScaleRef.current = window.visualViewport.scale

const handleViewportChange = debounce(() => {
if (window.visualViewport) {
const currentScale = window.visualViewport.scale
const isZooming = currentScale !== initialScaleRef.current
if (!isZooming) {
const currentHeight = window.visualViewport.height
const keyboardVisible = initialHeightRef.current - currentHeight > KEYBOARD_VISIBILITY_THRESHOLD
setIsKeyboardVisible(keyboardVisible)
setAvailablePanelHeight(keyboardVisible ? currentHeight : undefined)
}
}
}, 100)

// keeping this check to satisfy typescript but need eslint to ignore redundancy rule
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (window.visualViewport) {
// Using visualViewport to more reliably detect viewport changes across different browsers, which specifically requires these listeners
// eslint-disable-next-line github/prefer-observers
window.visualViewport.addEventListener('resize', handleViewportChange)
// eslint-disable-next-line github/prefer-observers
window.visualViewport.addEventListener('scroll', handleViewportChange)
}

return () => {
if (window.visualViewport) {
window.visualViewport.removeEventListener('resize', handleViewportChange)
window.visualViewport.removeEventListener('scroll', handleViewportChange)
}
handleViewportChange.cancel()
}
}, [open, isNarrowScreenSize])

const anchorRef = useProvidedRefOrCreate(externalAnchorRef)
const onOpen: AnchoredOverlayProps['onOpen'] = useCallback(
(gesture: Parameters<Exclude<AnchoredOverlayProps['onOpen'], undefined>>[0]) => onOpenChange(true, gesture),
Expand Down Expand Up @@ -649,6 +694,12 @@ function Panel({
'--max-height': overlayProps?.maxHeight ? heightMap[overlayProps.maxHeight] : heightMap['large'],
/* override AnchoredOverlay position */
transform: variant === 'modal' ? 'translate(-50%, -50%)' : undefined,
// set maxHeight based on calculated availablePanelHeight when keyboard is visible
...(isKeyboardVisible
? {
maxHeight: availablePanelHeight !== undefined ? `${availablePanelHeight}px` : 'auto',
}
: {}),
} as React.CSSProperties,
}}
focusTrapSettings={focusTrapSettings}
Expand Down
Loading