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

View File

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