Skip to content

Commit efb6fa9

Browse files
author
Dylan Huang
committed
better styling
1 parent 1b7ceb8 commit efb6fa9

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

vite-app/src/components/SearchableSelect.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const SearchableSelect = React.forwardRef<
3030
const [isOpen, setIsOpen] = useState(false);
3131
const [searchTerm, setSearchTerm] = useState("");
3232
const [filteredOptions, setFilteredOptions] = useState(options);
33+
const [dropdownPosition, setDropdownPosition] = useState<"left" | "right">(
34+
"left"
35+
);
3336
const containerRef = useRef<HTMLDivElement>(null);
3437
const inputRef = useRef<HTMLInputElement>(null);
3538

@@ -64,8 +67,25 @@ const SearchableSelect = React.forwardRef<
6467
setSearchTerm("");
6568
};
6669

70+
const calculateDropdownPosition = () => {
71+
if (!containerRef.current) return "left";
72+
73+
const rect = containerRef.current.getBoundingClientRect();
74+
const windowWidth = window.innerWidth;
75+
const estimatedDropdownWidth = 300; // Approximate width for dropdown content
76+
77+
// If dropdown would overflow right edge, position it to the left
78+
if (rect.left + estimatedDropdownWidth > windowWidth) {
79+
return "right";
80+
}
81+
return "left";
82+
};
83+
6784
const handleToggle = () => {
6885
if (!disabled) {
86+
if (!isOpen) {
87+
setDropdownPosition(calculateDropdownPosition());
88+
}
6989
setIsOpen(!isOpen);
7090
if (!isOpen) {
7191
setTimeout(() => inputRef.current?.focus(), 0);
@@ -109,15 +129,24 @@ const SearchableSelect = React.forwardRef<
109129
</div>
110130

111131
{isOpen && (
112-
<div className="absolute z-50 w-max min-w-full mt-1 bg-white border border-gray-200 rounded-md max-h-60 overflow-auto">
132+
<div
133+
className={`absolute z-50 w-max min-w-full mt-1 bg-white border border-gray-200 rounded-md max-h-60 overflow-auto ${
134+
dropdownPosition === "right" ? "right-0" : "left-0"
135+
}`}
136+
style={{
137+
maxWidth: `min(calc(100vw - 2rem), 500px)`,
138+
right: dropdownPosition === "right" ? "0" : undefined,
139+
left: dropdownPosition === "left" ? "0" : undefined,
140+
}}
141+
>
113142
<div className="p-2 border-b border-gray-200">
114143
<input
115144
ref={inputRef}
116145
type="text"
117146
value={searchTerm}
118147
onChange={(e) => setSearchTerm(e.target.value)}
119148
placeholder="Search..."
120-
className={`${commonStyles.input.base} ${commonStyles.input.size.sm} w-full`}
149+
className={`${commonStyles.input.base} ${commonStyles.input.size.sm} w-full min-w-48`}
121150
style={{ boxShadow: commonStyles.input.shadow }}
122151
onKeyDown={(e) => {
123152
if (e.key === "Escape") {

0 commit comments

Comments
 (0)