Improve dropdown component

This commit is contained in:
Arnaud 2024-08-28 10:03:09 +02:00
parent 3c314b455d
commit b325e249a3
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
2 changed files with 73 additions and 37 deletions

View File

@ -1,4 +1,10 @@
import { ChangeEvent, ComponentType, useState } from "react";
import {
ChangeEvent,
ComponentType,
useState,
KeyboardEvent,
useRef,
} from "react";
import "./dropdown.css";
import { attributes } from "../utils/attributes";
import { Backdrop } from "../Backdrop/Backdrop";
@ -67,12 +73,20 @@ type Props = {
* --codex-dropdown-option-background-hover
*/
style?: CustomStyleCSS;
label: string;
id: string;
Component?: ComponentType<DropdownOption>;
};
export function Dropdown({
placeholder,
style,
options,
label,
id,
onMouseEnter,
onMouseLeave,
onFocus,
@ -82,6 +96,7 @@ export function Dropdown({
value = "",
className = "",
}: Props) {
const inputRef = useRef<HTMLInputElement>(null);
const lower = value.toLocaleLowerCase();
const filtered = options.filter(
(o) =>
@ -105,25 +120,39 @@ export function Dropdown({
setFocused(false);
};
const onKeyUp = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Escape") {
onClose();
inputRef.current?.blur();
}
};
const onClose = () => setFocused(false);
const attr = attributes({ "aria-expanded": focused });
return (
<>
<label className="dropdown-label" htmlFor={id}>
{label}
</label>
<div className={`dropdown ${className}`} style={style}>
<Backdrop onClose={onClose} open={focused} />
<Input
ref={inputRef}
className="dropdown-input"
onChange={onChange}
onFocus={onInternalFocus}
onBlur={onInternalBlur}
onKeyUp={onKeyUp}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
placeholder={placeholder}
value={value}
label={""}
id={""}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
id={id}
/>
<div className="dropdown-panel" {...attr}>
@ -148,5 +177,6 @@ export function Dropdown({
)}
</div>
</div>
</>
);
}

View File

@ -24,11 +24,17 @@
z-index: -1;
}
.dropdown-label {
margin-bottom: 0.5rem;
font-weight: 500;
display: block;
color: var(--codex-color);
}
.dropdown-panel[aria-expanded] {
z-index: 2;
transform: translateY(0.5rem);
opacity: 1;
z-index: 2;
z-index: 10;
}
.dropdown-input {