104 lines
2.9 KiB
TypeScript
104 lines
2.9 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import FormField from "./FormField";
|
|
import PasswordField from "./PasswordField";
|
|
|
|
export type CredentialValues = {
|
|
username?: string | null;
|
|
password?: string | null;
|
|
};
|
|
|
|
export type CredentialFieldsProps = {
|
|
values: CredentialValues;
|
|
onChange: (patch: Partial<CredentialValues>) => void;
|
|
disabled?: boolean;
|
|
usernameDisabled?: boolean;
|
|
passwordDisabled?: boolean;
|
|
savedPassword?: boolean;
|
|
savedPasswordPlaceholder?: string;
|
|
heading?: ReactNode;
|
|
headingClassName?: string;
|
|
usernameLabel?: ReactNode;
|
|
passwordLabel?: ReactNode;
|
|
usernamePlaceholder?: string;
|
|
passwordPlaceholder?: string;
|
|
usernameAutoComplete?: string;
|
|
passwordAutoComplete?: string;
|
|
showUsername?: boolean;
|
|
showPassword?: boolean;
|
|
};
|
|
|
|
export type CredentialPanelProps = CredentialFieldsProps & {
|
|
className?: string;
|
|
gridClassName?: string;
|
|
children?: ReactNode;
|
|
};
|
|
|
|
export function CredentialFields({
|
|
values,
|
|
onChange,
|
|
disabled = false,
|
|
usernameDisabled = disabled,
|
|
passwordDisabled = disabled,
|
|
savedPassword = false,
|
|
savedPasswordPlaceholder = "••••••••",
|
|
heading,
|
|
headingClassName = "credential-panel-heading",
|
|
usernameLabel = "i18n:govoplan-core.username.84c29015",
|
|
passwordLabel = "i18n:govoplan-core.password.8be3c943",
|
|
usernamePlaceholder,
|
|
passwordPlaceholder,
|
|
usernameAutoComplete = "username",
|
|
passwordAutoComplete = "new-password",
|
|
showUsername = true,
|
|
showPassword = true
|
|
}: CredentialFieldsProps) {
|
|
return (
|
|
<>
|
|
{heading && <div className={headingClassName}>{heading}</div>}
|
|
{showUsername &&
|
|
<FormField label={usernameLabel}>
|
|
<input
|
|
value={stringValue(values.username)}
|
|
disabled={usernameDisabled}
|
|
autoComplete={usernameAutoComplete}
|
|
placeholder={usernamePlaceholder}
|
|
onChange={(event) => onChange({ username: event.target.value })} />
|
|
</FormField>
|
|
}
|
|
{showPassword &&
|
|
<FormField label={passwordLabel}>
|
|
<PasswordField
|
|
value={stringValue(values.password)}
|
|
disabled={passwordDisabled}
|
|
saved={savedPassword}
|
|
savedPlaceholder={savedPasswordPlaceholder}
|
|
placeholder={passwordPlaceholder}
|
|
autoComplete={passwordAutoComplete}
|
|
onValueChange={(password) => onChange({ password })} />
|
|
</FormField>
|
|
}
|
|
</>);
|
|
|
|
}
|
|
|
|
export default function CredentialPanel({
|
|
className = "",
|
|
gridClassName = "",
|
|
children,
|
|
...fieldProps
|
|
}: CredentialPanelProps) {
|
|
return (
|
|
<div className={`credential-panel ${className}`.trim()}>
|
|
<div className={`credential-panel-grid ${gridClassName}`.trim()}>
|
|
<CredentialFields {...fieldProps} />
|
|
</div>
|
|
{children && <div className="credential-panel-extra">{children}</div>}
|
|
</div>);
|
|
|
|
}
|
|
|
|
function stringValue(value: string | number | null | undefined): string {
|
|
if (value === null || value === undefined) return "";
|
|
return String(value);
|
|
}
|