vmui: improve select component functionality (#5755)

* vmui: fix select closing on click outside (#5728)

* vmui: clear entered text in select after selecting a value (#5727)

---------

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Yury Molodov 2024-02-06 21:50:04 +01:00 committed by Aliaksandr Valialkin
parent 0b5f5d456c
commit 5778acf9eb
No known key found for this signature in database
GPG key ID: 52C003EE2BCDB9EB
4 changed files with 16 additions and 3 deletions

View file

@ -30,6 +30,7 @@ interface AutocompleteProps {
onSelect: (val: string) => void onSelect: (val: string) => void
onOpenAutocomplete?: (val: boolean) => void onOpenAutocomplete?: (val: boolean) => void
onFoundOptions?: (val: AutocompleteOptions[]) => void onFoundOptions?: (val: AutocompleteOptions[]) => void
onChangeWrapperRef?: (elementRef: Ref<HTMLDivElement>) => void
} }
enum FocusType { enum FocusType {
@ -52,7 +53,8 @@ const Autocomplete: FC<AutocompleteProps> = ({
maxDisplayResults, maxDisplayResults,
onSelect, onSelect,
onOpenAutocomplete, onOpenAutocomplete,
onFoundOptions onFoundOptions,
onChangeWrapperRef
}) => { }) => {
const { isMobile } = useDeviceDetect(); const { isMobile } = useDeviceDetect();
const wrapperEl = useRef<HTMLDivElement>(null); const wrapperEl = useRef<HTMLDivElement>(null);
@ -166,6 +168,10 @@ const Autocomplete: FC<AutocompleteProps> = ({
onFoundOptions && onFoundOptions(hideFoundedOptions ? [] : foundOptions); onFoundOptions && onFoundOptions(hideFoundedOptions ? [] : foundOptions);
}, [foundOptions, hideFoundedOptions]); }, [foundOptions, hideFoundedOptions]);
useEffect(() => {
onChangeWrapperRef && onChangeWrapperRef(wrapperEl);
}, [wrapperEl]);
return ( return (
<Popper <Popper
open={openAutocomplete} open={openAutocomplete}

View file

@ -1,4 +1,4 @@
import React, { FC, useEffect, useMemo, useRef, useState, } from "preact/compat"; import React, { FC, Ref, useEffect, useMemo, useRef, useState, } from "preact/compat";
import classNames from "classnames"; import classNames from "classnames";
import { ArrowDropDownIcon, CloseIcon } from "../Icons"; import { ArrowDropDownIcon, CloseIcon } from "../Icons";
import { FormEvent, MouseEvent } from "react"; import { FormEvent, MouseEvent } from "react";
@ -8,6 +8,7 @@ import "./style.scss";
import useDeviceDetect from "../../../hooks/useDeviceDetect"; import useDeviceDetect from "../../../hooks/useDeviceDetect";
import MultipleSelectedValue from "./MultipleSelectedValue/MultipleSelectedValue"; import MultipleSelectedValue from "./MultipleSelectedValue/MultipleSelectedValue";
import useEventListener from "../../../hooks/useEventListener"; import useEventListener from "../../../hooks/useEventListener";
import useClickOutside from "../../../hooks/useClickOutside";
interface SelectProps { interface SelectProps {
value: string | string[] value: string | string[]
@ -39,6 +40,7 @@ const Select: FC<SelectProps> = ({
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const autocompleteAnchorEl = useRef<HTMLDivElement>(null); const autocompleteAnchorEl = useRef<HTMLDivElement>(null);
const [wrapperRef, setWrapperRef] = useState<Ref<HTMLDivElement> | null>(null);
const [openList, setOpenList] = useState(false); const [openList, setOpenList] = useState(false);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
@ -76,6 +78,7 @@ const Select: FC<SelectProps> = ({
}; };
const handleSelected = (val: string) => { const handleSelected = (val: string) => {
setSearch("");
onChange(val); onChange(val);
if (!isMultiple) handleCloseList(); if (!isMultiple) handleCloseList();
if (isMultiple && inputRef.current) inputRef.current.focus(); if (isMultiple && inputRef.current) inputRef.current.focus();
@ -110,6 +113,7 @@ const Select: FC<SelectProps> = ({
}, [autofocus, inputRef]); }, [autofocus, inputRef]);
useEventListener("keyup", handleKeyUp); useEventListener("keyup", handleKeyUp);
useClickOutside(autocompleteAnchorEl, handleCloseList, wrapperRef);
return ( return (
<div <div
@ -172,6 +176,7 @@ const Select: FC<SelectProps> = ({
noOptionsText={noOptionsText} noOptionsText={noOptionsText}
onSelect={handleSelected} onSelect={handleSelected}
onOpenAutocomplete={setOpenList} onOpenAutocomplete={setOpenList}
onChangeWrapperRef={setWrapperRef}
/> />
</div> </div>
); );

View file

@ -7,7 +7,7 @@ type Event = MouseEvent | TouchEvent;
const useClickOutside = <T extends HTMLElement = HTMLElement>( const useClickOutside = <T extends HTMLElement = HTMLElement>(
ref: RefObject<T>, ref: RefObject<T>,
handler: (event: Event) => void, handler: (event: Event) => void,
preventRef?: RefObject<T> preventRef?: RefObject<T> | null
) => { ) => {
const listener = useCallback((event: Event) => { const listener = useCallback((event: Event) => {
const el = ref?.current; const el = ref?.current;

View file

@ -36,6 +36,8 @@ The sandbox cluster installation is running under the constant load generated by
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly propagate [label filters](https://docs.victoriametrics.com/keyconcepts/#filtering) from multiple arguments passed to [aggregate functions](https://docs.victoriametrics.com/metricsql/#aggregate-functions). For example, `sum({job="foo"}, {job="bar"}) by (job) + a` was improperly optimized to `sum({job="foo"}, {job="bar"}) by (job) + a{job="foo"}` before being executed. This could lead to unexpected results. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5604). * BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly propagate [label filters](https://docs.victoriametrics.com/keyconcepts/#filtering) from multiple arguments passed to [aggregate functions](https://docs.victoriametrics.com/metricsql/#aggregate-functions). For example, `sum({job="foo"}, {job="bar"}) by (job) + a` was improperly optimized to `sum({job="foo"}, {job="bar"}) by (job) + a{job="foo"}` before being executed. This could lead to unexpected results. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5604).
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix the graph dragging for Firefox and Safari. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5764). * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix the graph dragging for Firefox and Safari. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5764).
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix handling invalid timezone. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5732). * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix handling invalid timezone. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5732).
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix the bug where the select does not open. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5728).
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): clear entered text in select after selecting a value. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5727).
## [v1.97.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.97.1) ## [v1.97.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.97.1)