diff --git a/packages/ui/src/components/PasswordField/PasswordField.tsx b/packages/ui/src/components/PasswordField/PasswordField.tsx index c2cfdd1081..9a69418e3d 100644 --- a/packages/ui/src/components/PasswordField/PasswordField.tsx +++ b/packages/ui/src/components/PasswordField/PasswordField.tsx @@ -20,15 +20,13 @@ import { TextField as AriaTextField, Button as RAButton, } from 'react-aria-components'; -import clsx from 'clsx'; import { FieldLabel } from '../FieldLabel'; import { FieldError } from '../FieldError'; import type { PasswordFieldProps } from './types'; -import { useStyles } from '../../hooks/useStyles'; +import { useDefinition } from '../../hooks/useDefinition'; import { PasswordFieldDefinition } from './definition'; import { RiEyeLine, RiEyeOffLine } from '@remixicon/react'; -import stylesPasswordField from './PasswordField.module.css'; /** @public */ export const PasswordField = forwardRef( @@ -47,24 +45,18 @@ export const PasswordField = forwardRef( } }, [label, ariaLabel, ariaLabelledBy]); + const { ownProps, restProps, dataAttributes } = useDefinition( + PasswordFieldDefinition, + props, + ); const { - classNames: classNamesPasswordField, - dataAttributes, - cleanedProps, - } = useStyles(PasswordFieldDefinition, { - size: 'small', - ...props, - }); - - const { - className, - description, + classes, icon, isRequired, secondaryLabel, placeholder, - ...rest - } = cleanedProps; + description, + } = ownProps; // If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required. const secondaryLabelText = @@ -75,16 +67,12 @@ export const PasswordField = forwardRef( return ( ( description={description} />
{icon && ( )} ( aria-controls={isVisible ? 'text' : 'password'} aria-expanded={isVisible} onPress={() => setIsVisible(v => !v)} - className={clsx( - classNamesPasswordField.inputVisibility, - stylesPasswordField[classNamesPasswordField.inputVisibility], - )} + className={classes.inputVisibility} > {isVisible ? : } diff --git a/packages/ui/src/components/PasswordField/definition.ts b/packages/ui/src/components/PasswordField/definition.ts index 11272494b4..2c58959536 100644 --- a/packages/ui/src/components/PasswordField/definition.ts +++ b/packages/ui/src/components/PasswordField/definition.ts @@ -14,21 +14,32 @@ * limitations under the License. */ -import type { ComponentDefinition } from '../../types'; +import { defineComponent } from '../../hooks/useDefinition'; +import type { PasswordFieldOwnProps } from './types'; +import styles from './PasswordField.module.css'; /** * Component definition for PasswordField * @public */ -export const PasswordFieldDefinition = { - classNames: { - root: 'bui-PasswordField', - inputWrapper: 'bui-PasswordFieldInputWrapper', - input: 'bui-PasswordFieldInput', - inputIcon: 'bui-PasswordFieldIcon', - inputVisibility: 'bui-PasswordFieldVisibility', +export const PasswordFieldDefinition = defineComponent()( + { + styles, + classNames: { + root: 'bui-PasswordField', + inputWrapper: 'bui-PasswordFieldInputWrapper', + input: 'bui-PasswordFieldInput', + inputIcon: 'bui-PasswordFieldIcon', + inputVisibility: 'bui-PasswordFieldVisibility', + }, + propDefs: { + size: { dataAttribute: true, default: 'small' }, + className: {}, + icon: {}, + placeholder: {}, + description: {}, + secondaryLabel: {}, + isRequired: {}, + }, }, - dataAttributes: { - size: ['small', 'medium'] as const, - }, -} as const satisfies ComponentDefinition; +); diff --git a/packages/ui/src/components/PasswordField/types.ts b/packages/ui/src/components/PasswordField/types.ts index 6fade7496a..b5be8e3493 100644 --- a/packages/ui/src/components/PasswordField/types.ts +++ b/packages/ui/src/components/PasswordField/types.ts @@ -15,27 +15,40 @@ */ import type { TextFieldProps as AriaTextFieldProps } from 'react-aria-components'; -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import type { Breakpoint } from '../../types'; import type { FieldLabelProps } from '../FieldLabel/types'; /** @public */ -export interface PasswordFieldProps - extends AriaTextFieldProps, - Omit { - /** - * An icon to render before the input - */ - icon?: ReactNode; - +export type PasswordFieldOwnProps = { /** * The size of the password field * @defaultValue 'medium' */ size?: 'small' | 'medium' | Partial>; + className?: string; + + /** + * An icon to render before the input + */ + icon?: ReactNode; + /** * Text to display in the input when it has no value */ placeholder?: string; -} + + description?: FieldLabelProps['description']; + secondaryLabel?: FieldLabelProps['secondaryLabel']; + isRequired?: boolean; +}; + +/** @public */ +export interface PasswordFieldProps + extends Omit, + Omit< + FieldLabelProps, + 'htmlFor' | 'id' | 'className' | 'description' | 'secondaryLabel' + >, + PasswordFieldOwnProps {}