diff --git a/src/design-system/index.ts b/src/design-system/index.ts index 16cd1f5..7d805b9 100644 --- a/src/design-system/index.ts +++ b/src/design-system/index.ts @@ -24,7 +24,13 @@ export { ToastBar } from './toast-bar'; export * from './tooltip'; export { Message } from './message'; export { Metadata, MetadataLink } from './metadata'; -export { PasswordBox } from './password-box'; +export { PasswordBox, UncontrolledPasswordBox } from './password-box'; +export type { + UncontrolledPasswordBoxProps, + PasswordBoxProps, + OnPasswordChange, + Password, +} from './password-box'; export { TextLink } from './text-link'; export * as ProfileDropdown from './profile-dropdown'; export type { AccountData } from './profile-dropdown'; diff --git a/src/design-system/password-box/index.ts b/src/design-system/password-box/index.ts index 94342c8..bd7c9f5 100644 --- a/src/design-system/password-box/index.ts +++ b/src/design-system/password-box/index.ts @@ -1,2 +1,8 @@ export { PasswordBox } from './password-box.component'; export type { PasswordBoxProps } from './password-box.component'; +export { UncontrolledPasswordBox } from './uncontrolled-password-box.component'; +export type { UncontrolledPasswordBoxProps } from './uncontrolled-password-box.component'; +export type { + OnPasswordChange, + Password, +} from './uncontrolled-password-box-input.component'; diff --git a/src/design-system/password-box/uncontrolled-password-box-input.component.tsx b/src/design-system/password-box/uncontrolled-password-box-input.component.tsx new file mode 100644 index 0000000..04d1c00 --- /dev/null +++ b/src/design-system/password-box/uncontrolled-password-box-input.component.tsx @@ -0,0 +1,102 @@ +import React, { useState } from 'react'; + +import * as Form from '@radix-ui/react-form'; +import cn from 'classnames'; + +import { Flex } from '../flex'; +import { Text } from '../text'; + +import { PasswordInputButton } from './password-box-button.component'; +import * as cx from './password-box-input.css'; + +export type Password = { + input: HTMLInputElement; + // TODO: convert this to UInt8Array + value: string; +}; + +export type OnPasswordChange = (event: Readonly) => void; + +export interface UncontrolledPasswordInputProps + extends Omit { + required?: boolean; + disabled?: boolean; + id?: string; + label: string; + name?: string; + errorMessage?: string; + onChange: OnPasswordChange; + defaultIsPasswordVisible?: boolean; + containerClassName?: string; + containerStyle?: React.CSSProperties; + testId?: string; +} + +export const UncontrolledPasswordInput = ({ + required = false, + disabled = false, + id, + label, + name, + errorMessage = '', + containerClassName = '', + onChange, + defaultIsPasswordVisible = false, + containerStyle, + testId, +}: Readonly): JSX.Element => { + const [isPasswordVisible, setIsPasswordVisible] = useState( + defaultIsPasswordVisible, + ); + + const onChangeHandler: React.ChangeEventHandler = event => + onChange({ input: event.target, value: event.target.value }); + + return ( +
+ + + + + + + {label} + + { + event.preventDefault(); + setIsPasswordVisible(!isPasswordVisible); + }} + disabled={disabled} + isPasswordVisible={isPasswordVisible} + /> + + + {errorMessage && ( + + {errorMessage} + + )} +
+ ); +}; diff --git a/src/design-system/password-box/uncontrolled-password-box.component.tsx b/src/design-system/password-box/uncontrolled-password-box.component.tsx new file mode 100644 index 0000000..c6737a8 --- /dev/null +++ b/src/design-system/password-box/uncontrolled-password-box.component.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +import * as Form from '@radix-ui/react-form'; + +import { UncontrolledPasswordInput } from './uncontrolled-password-box-input.component'; + +import type { UncontrolledPasswordInputProps } from './uncontrolled-password-box-input.component'; + +export interface UncontrolledPasswordBoxProps + extends UncontrolledPasswordInputProps { + rootStyle?: React.CSSProperties; + onSubmit: (event: Readonly) => void; +} + +export const UncontrolledPasswordBox = ({ + rootStyle, + onSubmit, + ...props +}: Readonly): JSX.Element => { + return ( + + + + ); +};