Feat: make text input capable of support dropdown inputs also

This commit is contained in:
igorrCarvalho 2024-02-05 11:42:08 -03:00
commit 86ccae87fb
3 changed files with 142 additions and 30 deletions

View file

@ -1,8 +1,10 @@
import { Listbox, Transition } from "@headlessui/react";
import * as Form from "@radix-ui/react-form";
import { useEffect, useRef, useState } from "react";
import { Fragment, useEffect, useRef, useState } from "react";
import { InputComponentType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { classNames } from "../../utils/utils";
import IconComponent from "../genericIconComponent";
import { Input } from "../ui/input";
export default function InputComponent({
@ -19,9 +21,11 @@ export default function InputComponent({
className,
id = "",
blurOnEnter = false,
options = [],
}: InputComponentType): JSX.Element {
const [pwdVisible, setPwdVisible] = useState(false);
const refInput = useRef<HTMLInputElement>(null);
const [showOptions, setShowOptions] = useState<boolean>(false);
// Clear component state
useEffect(() => {
if (disabled && value !== "") {
@ -29,6 +33,11 @@ export default function InputComponent({
}
}, [disabled]);
function onInputLostFocus(event): void {
if (onBlur) onBlur(event);
setShowOptions(false);
}
return (
<div className="relative w-full">
{isForm ? (
@ -36,7 +45,7 @@ export default function InputComponent({
<Input
id={"form-" + id}
ref={refInput}
onBlur={onBlur}
onBlur={onInputLostFocus}
autoFocus={autoFocus}
type={password && !pwdVisible ? "password" : "text"}
value={value}
@ -65,34 +74,136 @@ export default function InputComponent({
/>
</Form.Control>
) : (
<Input
id={id}
ref={refInput}
type="text"
onBlur={onBlur}
value={value}
autoFocus={autoFocus}
disabled={disabled}
required={required}
className={classNames(
password && !pwdVisible && value !== ""
? " text-clip password "
: "",
editNode ? " input-edit-node " : "",
password && editNode ? "pr-8" : "",
password && !editNode ? "pr-10" : "",
className!
)}
placeholder={password && editNode ? "Key" : placeholder}
onChange={(e) => {
onChange(e.target.value);
}}
onKeyDown={(e) => {
handleKeyDown(e, value, "");
if (blurOnEnter && e.key === "Enter") refInput.current?.blur();
}}
/>
<>
<Input
id={id}
ref={refInput}
type="text"
onBlur={(e) => setShowOptions(false)}
value={value}
autoFocus={autoFocus}
disabled={disabled}
required={required}
className={classNames(
password && !pwdVisible && value !== ""
? " text-clip password "
: "",
editNode ? " input-edit-node " : "",
password && editNode ? "pr-8" : "",
password && !editNode ? "pr-10" : "",
className!
)}
placeholder={password && editNode ? "Key" : placeholder}
onChange={(e) => {
onChange(e.target.value);
setShowOptions(false);
}}
onKeyDown={(e) => {
handleKeyDown(e, value, "");
if (blurOnEnter && e.key === "Enter") refInput.current?.blur();
}}
onFocus={() => setShowOptions(true)}
/>
{
/* options.length > 0 */ true ? (
<Listbox
onChange={(val) => {
onChange(val);
}}
>
<>
<div className={"relative mt-1"}>
<Transition
show={showOptions}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options
className={classNames(
editNode
? "dropdown-component-true-options nowheel custom-scroll"
: "dropdown-component-false-options nowheel custom-scroll",
false ? "mb-2 w-[250px]" : "absolute w-full"
)}
>
{["key", "key2", "key3", "key4", "key5"].map(
(option, id) => (
<Listbox.Option
key={id}
className={({ active }) =>
classNames(
active ? " bg-accent" : "",
editNode
? "dropdown-component-false-option"
: "dropdown-component-true-option",
" hover:bg-accent"
)
}
value={option}
>
{({ selected, active }) => (
<>
<span
className={classNames(
selected
? "font-semibold"
: "font-normal",
"block truncate "
)}
data-testid={`${option}-${id ?? ""}-option`}
>
{option}
</span>
{selected ? (
<span
className={classNames(
active ? "text-background " : "",
"dropdown-component-choosal"
)}
>
<IconComponent
name="Check"
className={
active
? "dropdown-component-check-icon"
: "dropdown-component-check-icon"
}
aria-hidden="true"
/>
</span>
) : null}
</>
)}
</Listbox.Option>
)
)}
</Listbox.Options>
</Transition>
</div>
</>
</Listbox>
) : null
}
</>
)}
<span
className={
password
? "dropdown-component-arrow right-8"
: "dropdown-component-arrow right-0"
}
>
<IconComponent
name="ChevronsUpDown"
className="dropdown-component-arrow-color"
aria-hidden="true"
/>
</span>
{password && (
<button
type="button"

View file

@ -422,7 +422,7 @@
@apply block w-full truncate bg-background;
}
.dropdown-component-arrow {
@apply pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2;
@apply pointer-events-none absolute inset-y-0 flex items-center pr-2;
}
.dropdown-component-arrow-color {
@apply extra-side-bar-save-disable h-5 w-5;

View file

@ -20,6 +20,7 @@ export type InputComponentType = {
className?: string;
id?: string;
blurOnEnter?: boolean;
options?: string[];
};
export type ToggleComponentType = {
enabled: boolean;