From dbf64fc345ee2fab67180e01656cdddb5bb8d407 Mon Sep 17 00:00:00 2001 From: Johan Persson Date: Wed, 25 Feb 2026 11:37:28 +0100 Subject: [PATCH] Fix PasswordField: move label into OwnProps, remove FieldLabelProps extension, useDefinition first - Add label to PasswordFieldOwnProps and propDefs - Remove Omit from PasswordFieldProps - Move useDefinition call to top of component - Access aria-label/aria-labelledby from restProps instead of props Signed-off-by: Johan Persson --- packages/ui/report.api.md | 6 ++--- .../PasswordField/PasswordField.tsx | 25 +++++++------------ .../components/PasswordField/definition.ts | 1 + .../ui/src/components/PasswordField/types.ts | 5 +--- 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 4d78717f91..99516f6e4b 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -1616,6 +1616,7 @@ export const PasswordFieldDefinition: { readonly className: {}; readonly icon: {}; readonly placeholder: {}; + readonly label: {}; readonly description: {}; readonly secondaryLabel: {}; readonly isRequired: {}; @@ -1628,6 +1629,7 @@ export type PasswordFieldOwnProps = { className?: string; icon?: ReactNode; placeholder?: string; + label?: FieldLabelProps['label']; description?: FieldLabelProps['description']; secondaryLabel?: FieldLabelProps['secondaryLabel']; isRequired?: boolean; @@ -1636,10 +1638,6 @@ export type PasswordFieldOwnProps = { // @public (undocumented) export interface PasswordFieldProps extends Omit, - Omit< - FieldLabelProps, - 'htmlFor' | 'id' | 'className' | 'description' | 'secondaryLabel' - >, PasswordFieldOwnProps {} // @public diff --git a/packages/ui/src/components/PasswordField/PasswordField.tsx b/packages/ui/src/components/PasswordField/PasswordField.tsx index 9a69418e3d..721341a5d4 100644 --- a/packages/ui/src/components/PasswordField/PasswordField.tsx +++ b/packages/ui/src/components/PasswordField/PasswordField.tsx @@ -31,26 +31,13 @@ import { RiEyeLine, RiEyeOffLine } from '@remixicon/react'; /** @public */ export const PasswordField = forwardRef( (props, ref) => { - const { - label, - 'aria-label': ariaLabel, - 'aria-labelledby': ariaLabelledBy, - } = props; - - useEffect(() => { - if (!label && !ariaLabel && !ariaLabelledBy) { - console.warn( - 'PasswordField requires either a visible label, aria-label, or aria-labelledby for accessibility', - ); - } - }, [label, ariaLabel, ariaLabelledBy]); - const { ownProps, restProps, dataAttributes } = useDefinition( PasswordFieldDefinition, props, ); const { classes, + label, icon, isRequired, secondaryLabel, @@ -58,6 +45,14 @@ export const PasswordField = forwardRef( description, } = ownProps; + useEffect(() => { + if (!label && !restProps['aria-label'] && !restProps['aria-labelledby']) { + console.warn( + 'PasswordField requires either a visible label, aria-label, or aria-labelledby for accessibility', + ); + } + }, [label, restProps['aria-label'], restProps['aria-labelledby']]); + // If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required. const secondaryLabelText = secondaryLabel || (isRequired ? 'Required' : null); @@ -69,8 +64,6 @@ export const PasswordField = forwardRef( ()( className: {}, icon: {}, placeholder: {}, + label: {}, description: {}, secondaryLabel: {}, isRequired: {}, diff --git a/packages/ui/src/components/PasswordField/types.ts b/packages/ui/src/components/PasswordField/types.ts index b5be8e3493..6b29317802 100644 --- a/packages/ui/src/components/PasswordField/types.ts +++ b/packages/ui/src/components/PasswordField/types.ts @@ -39,6 +39,7 @@ export type PasswordFieldOwnProps = { */ placeholder?: string; + label?: FieldLabelProps['label']; description?: FieldLabelProps['description']; secondaryLabel?: FieldLabelProps['secondaryLabel']; isRequired?: boolean; @@ -47,8 +48,4 @@ export type PasswordFieldOwnProps = { /** @public */ export interface PasswordFieldProps extends Omit, - Omit< - FieldLabelProps, - 'htmlFor' | 'id' | 'className' | 'description' | 'secondaryLabel' - >, PasswordFieldOwnProps {}