You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
3.4 KiB
141 lines
3.4 KiB
import { useEffect, useRef } from "react";
|
|
import { Button, type ButtonVariant } from "@components/UI/Button.tsx";
|
|
import { Input } from "@components/UI/Input.tsx";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@components/UI/Select.tsx";
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
export interface ActionButton {
|
|
text: string;
|
|
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
|
variant: ButtonVariant;
|
|
className?: string;
|
|
}
|
|
[];
|
|
|
|
export interface GeneratorProps extends React.BaseHTMLAttributes<HTMLElement> {
|
|
type: "text" | "password";
|
|
devicePSKBitCount?: number;
|
|
value: string;
|
|
id: string;
|
|
variant: "default" | "invalid" | "dirty";
|
|
actionButtons: ActionButton[];
|
|
bits?: { text: string; value: string; key: string }[];
|
|
selectChange: (event: string) => void;
|
|
inputChange: React.ChangeEventHandler<HTMLInputElement>;
|
|
showPasswordToggle?: boolean;
|
|
showCopyButton?: boolean;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
const Generator = (
|
|
{
|
|
type,
|
|
devicePSKBitCount,
|
|
id = "pskInput",
|
|
variant,
|
|
value,
|
|
actionButtons,
|
|
bits,
|
|
selectChange,
|
|
inputChange,
|
|
disabled,
|
|
showPasswordToggle,
|
|
showCopyButton,
|
|
...props
|
|
}: GeneratorProps,
|
|
) => {
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
const { t } = useTranslation();
|
|
|
|
const passwordRequiredBitSize = bits ? bits : [
|
|
{
|
|
text: t("security.256bit"),
|
|
value: "32",
|
|
key: "bit256",
|
|
},
|
|
{
|
|
text: t("security.128bit"),
|
|
value: "16",
|
|
key: "bit128",
|
|
},
|
|
{
|
|
text: t("security.8bit"),
|
|
value: "1",
|
|
key: "bit8",
|
|
},
|
|
{
|
|
text: t("security.empty"),
|
|
value: "0",
|
|
key: "bit0",
|
|
},
|
|
];
|
|
|
|
// Invokes onChange event on the input element when the value changes from the parent component
|
|
useEffect(() => {
|
|
if (!inputRef.current) return;
|
|
const setValue = Object.getOwnPropertyDescriptor(
|
|
HTMLInputElement.prototype,
|
|
"value",
|
|
)?.set;
|
|
|
|
if (!setValue) return;
|
|
inputRef.current.value = "";
|
|
setValue.call(inputRef.current, value);
|
|
inputRef.current.dispatchEvent(new Event("input", { bubbles: true }));
|
|
}, [value]);
|
|
return (
|
|
<>
|
|
<Input
|
|
type={type}
|
|
id={id}
|
|
variant={variant}
|
|
value={value}
|
|
onChange={inputChange}
|
|
disabled={disabled}
|
|
ref={inputRef}
|
|
showCopyButton={showCopyButton}
|
|
showPasswordToggle={showPasswordToggle}
|
|
/>
|
|
<Select
|
|
value={devicePSKBitCount?.toString()}
|
|
onValueChange={(e) => selectChange(e)}
|
|
disabled={disabled}
|
|
>
|
|
<SelectTrigger className="w-36 ml-2">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent className="w-36">
|
|
{passwordRequiredBitSize.map(({ text, value, key }) => (
|
|
<SelectItem key={key} value={value} className="w-36">
|
|
{text}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<div className="flex ml-2 space-x-2">
|
|
{actionButtons?.map(({ text, onClick, variant, className }) => (
|
|
<Button
|
|
key={text}
|
|
type="button"
|
|
onClick={onClick}
|
|
disabled={disabled}
|
|
variant={variant}
|
|
className={className}
|
|
{...props}
|
|
>
|
|
{text}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
Generator.displayName = "Button";
|
|
|
|
export { Generator };
|
|
|