Yes, it is possible to create a dropdown with a sticky header and footer, and a scrollable middle/content part. In the provided code using @floating-ui/react
, you can achieve this behavior by making use of CSS and the position: sticky
property.
To make the header and footer sticky, you can add the following CSS styles to the header and footer elements within the dropdown:
/* App.css or any other suitable CSS file */
.dropdown-container h3 {
position: sticky;
top: 0;
background-color: #f1f1f1;
padding: 10px;
}
.dropdown-container h3:last-child {
position: sticky;
bottom: 0;
background-color: #f1f1f1;
padding: 10px;
}
Here's the updated App component with the necessary CSS styles:
import * as React from 'react';
import { useState } from 'react';
import {
autoUpdate,
useFloating,
useClick,
useDismiss,
offset,
flip,
size,
useInteractions,
FloatingPortal,
} from '@floating-ui/react';
import './style.css';
const OFFSET = 10;
export default function App() {
const [isOpen, setIsOpen] = useState(false);
const { refs, floatingStyles, context, strategy } = useFloating({
placement: 'bottom-start',
open: isOpen,
onOpenChange: setIsOpen,
whileElementMounted: autoUpdate,
middleware: [
offset(OFFSET),
flip(),
size({
apply: ({ availableHeight, elements }) => {
Object.assign(elements.floating.style, {
maxHeight: `${Math.max(50, availableHeight - OFFSET)}px`,
});
},
}),
],
});
const click = useClick(context);
const dismiss = useDismiss(context);
const { getReferenceProps, getFloatingProps } = useInteractions([
click,
dismiss,
]);
return (
<>
<button {...getReferenceProps({ ref: refs.setReference })}>
open dropdown
</button>
{isOpen && (
<FloatingPortal>
<div
className="dropdown-container"
{...getFloatingProps({
ref: refs.setFloating,
style: { ...floatingStyles, position: strategy },
})}
>
<h3>Dropdown header (make me sticky)</h3>
<ul>
{Array.from({ length: 100 }).map((_, index) => (
<li key={index}>{index}. list item</li>
))}
</ul>
<h3>Dropdown footer (make me sticky)</h3>
</div>
</FloatingPortal>
)}
</>
);
}
With the above CSS styles, the <h3>
elements inside the .dropdown-container
will become sticky at the top and bottom respectively, creating the sticky header and footer effect. The middle/content part, represented by the <ul>
element, will be scrollable when the content exceeds the available height.
Please note that position: sticky
has some browser compatibility considerations, so ensure that it works as expected in your target browsers. The provided CSS styles are suitable for modern web browsers that support position: sticky
.