@payfit/unity-components 2.5.4 → 2.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,16 @@
1
1
  import { jsx as n } from "react/jsx-runtime";
2
- import { forwardRef as l } from "react";
3
- import { useStore as s } from "@tanstack/react-form";
2
+ import { forwardRef as s } from "react";
3
+ import { useStore as l } from "@tanstack/react-form";
4
4
  import { useFieldContext as c } from "../../../hooks/tanstack-form-context.js";
5
5
  import { Text as f } from "../../text/Text.js";
6
6
  import { useFieldA11yContext as u } from "../TanstackFormField.context.js";
7
- const x = l((r, t) => {
8
- const a = c(), i = u(), { errors: o, invalid: d, isTouched: m } = s(a.store, (e) => ({
9
- errors: e.meta.errors,
10
- invalid: !e.meta.isValid,
11
- isTouched: e.meta.isTouched
7
+ const p = s((r, t) => {
8
+ const a = c(), i = u(), { errors: e, invalid: d, isTouched: m } = l(a.store, (o) => ({
9
+ errors: o.meta.errors,
10
+ invalid: !o.meta.isValid,
11
+ isTouched: o.meta.isTouched
12
12
  }));
13
- return !m || !d || o.length === 0 ? null : /* @__PURE__ */ n(
13
+ return !m || !d || e.length === 0 ? null : /* @__PURE__ */ n(
14
14
  f,
15
15
  {
16
16
  "data-dd-privacy": "allow",
@@ -22,11 +22,11 @@ const x = l((r, t) => {
22
22
  variant: "bodySmallStrong",
23
23
  color: "content.form.invalid",
24
24
  asElement: "span",
25
- children: o[0].message
25
+ children: typeof e[0] == "object" && "message" in e[0] ? e[0].message : e[0]
26
26
  }
27
27
  );
28
28
  });
29
- x.displayName = "TanstackFormFeedbackText";
29
+ p.displayName = "TanstackFormFeedbackText";
30
30
  export {
31
- x as TanstackFormFeedbackText
31
+ p as TanstackFormFeedbackText
32
32
  };
@@ -1,21 +1,22 @@
1
- import { jsx as a } from "react/jsx-runtime";
1
+ import { jsx as o } from "react/jsx-runtime";
2
2
  import { forwardRef as l } from "react";
3
3
  import { Text as m } from "../../text/Text.js";
4
4
  import { useFieldA11yContext as n } from "../TanstackFormField.context.js";
5
- const d = l(({ children: e, ...t }, r) => {
6
- const o = n();
7
- return /* @__PURE__ */ a(
5
+ const d = l(({ children: t, ...e }, a) => {
6
+ const r = n();
7
+ return /* @__PURE__ */ o(
8
8
  m,
9
9
  {
10
10
  "data-dd-privacy": "allow",
11
- ...t,
12
- id: o.helperTextId || t.id,
11
+ ...e,
12
+ id: r.helperTextId || e.id,
13
13
  "data-unity-slot": "form-field-helper-text",
14
14
  variant: "bodySmall",
15
15
  asElement: "span",
16
16
  color: "content.neutral.low",
17
- ref: r,
18
- children: e
17
+ className: "uy:leading-[1]!",
18
+ ref: a,
19
+ children: t
19
20
  }
20
21
  );
21
22
  });
@@ -0,0 +1,113 @@
1
+ import { ReactNode } from 'react';
2
+ import { LabelProps } from '../label/Label.js';
3
+ import { PasswordInputProps } from './parts/PasswordInput.js';
4
+ import { PasswordRule } from './types.js';
5
+ export interface TanstackPasswordFieldProps extends Omit<PasswordInputProps, 'name' | 'value' | 'defaultValue' | 'isInvalid'>, Pick<LabelProps, 'isRequired' | 'requiredVariant'> {
6
+ /** Label for the password field */
7
+ label: string;
8
+ /** Helper text below the label */
9
+ helperText?: ReactNode;
10
+ /** Title for the validation rules section (default: "Your password must have:") */
11
+ rulesTitle?: ReactNode;
12
+ /** Array of password rules to display - status is controlled by consumer */
13
+ rules?: PasswordRule[];
14
+ /** A contextual link to display below the text field. */
15
+ contextualLink?: ReactNode;
16
+ /** Callback function to be called when the clear button is pressed */
17
+ onClearButtonPress?: () => void;
18
+ }
19
+ /**
20
+ * The `TanstackPasswordField` component provides a complete password input solution with visibility toggle,
21
+ * validation rules display, and caps lock detection, fully integrated with TanStack Form.
22
+ *
23
+ * Use this component to collect password input with real-time validation feedback. The component displays
24
+ * a list of password requirements that update dynamically as users type, helping them create passwords
25
+ * that meet your security criteria.
26
+ *
27
+ * The component acts as a **presentation layer only**. Define all validation logic externally using
28
+ * TanStack Form validators, then pass the evaluated rule statuses to the component for display.
29
+ *
30
+ * **Key features:**
31
+ * - Password visibility toggle for showing/hiding entered text
32
+ * - Real-time validation rules display with checked/unchecked visual feedback
33
+ * - Caps Lock warning indicator to prevent accidental input mistakes
34
+ * - Full accessibility support with ARIA labels and keyboard navigation
35
+ * - Integration with TanStack Form for validation and state management
36
+ * - Contextual link support for "Forgot password?" or similar actions
37
+ *
38
+ * **Important props:**
39
+ * - `label` — Required text label for the field
40
+ * - `rules` — Array of password rules with their validation status (you control the logic)
41
+ * - `helperText` — Optional helper text displayed below the label
42
+ * - `rulesTitle` — Custom title for the rules section (defaults to "Your password must have:")
43
+ * - `showCapsLockWarning` — Enable/disable caps lock detection (default: true)
44
+ * - `autoComplete` — Browser autocomplete hint: 'current-password' or 'new-password'
45
+ * - `contextualLink` — Optional link element (e.g., "Forgot password?")
46
+ * @param {TanstackPasswordFieldProps} props - Component properties
47
+ * @example
48
+ * ```tsx
49
+ * import { useTanstackUnityForm, fieldRevalidateLogic } from '@payfit/unity-components'
50
+ * import { z } from 'zod'
51
+ *
52
+ * function PasswordForm() {
53
+ * const ruleDefs = [
54
+ * {
55
+ * id: 'length',
56
+ * label: 'At least 10 characters',
57
+ * validate: (value: string) => value.length >= 10
58
+ * }
59
+ * ]
60
+ *
61
+ * const form = useTanstackUnityForm({
62
+ * defaultValues: { password: '' },
63
+ * validationLogic: fieldRevalidateLogic({
64
+ * whenPristine: 'blur',
65
+ * whenDirty: 'change',
66
+ * fields: ['password'],
67
+ * })
68
+ * })
69
+ *
70
+ * return (
71
+ * <form.AppForm>
72
+ * <form.Form>
73
+ * <form.AppField name="password">
74
+ * {(field) => {
75
+ * const rules = ruleDefs.map(rule => ({
76
+ * id: rule.id,
77
+ * label: rule.label,
78
+ * status: rule.validate(field.state.value) ? 'checked' : 'unchecked'
79
+ * }))
80
+ *
81
+ * return (
82
+ * <field.PasswordField
83
+ * label="Create Password"
84
+ * rules={rules}
85
+ * isRequired
86
+ * />
87
+ * )
88
+ * }}
89
+ * </form.AppField>
90
+ * </form.Form>
91
+ * </form.AppForm>
92
+ * )
93
+ * }
94
+ * ```
95
+ * @remarks
96
+ * - Access the component via `<field.PasswordField>` within `<form.AppField name="...">` scope
97
+ * - Do not pass `name`, `value`, or `isInvalid` props — these are managed by TanStack Form context
98
+ * - The `rules` prop is purely presentational — compute rule statuses in your component and pass them in
99
+ * - For async validation (e.g., checking password breaches), use TanStack Form's `onDynamicAsync` validator
100
+ * - Use `autoComplete="current-password"` for login forms and `autoComplete="new-password"` for registration
101
+ * - **New to password fields?** See the step-by-step tutorial in the developer docs
102
+ * - **Want to understand the architecture?** Read the validation guide in the developer docs
103
+ * @see {@link TanstackPasswordFieldProps} for all available props
104
+ * @see {@link useTanstackUnityForm} for form setup and validation
105
+ * @see Tutorial: Adding Password Field with Validation in the developer docs
106
+ * @see Guide: Understanding Password Field Validation in the developer docs
107
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/components/password-field GitHub}
108
+ * @see Design specs in {@link https://www.figma.com/design/poaMyU7abAgL9VRhx4ygyy/Unity-DS-%3E-Components-Library Figma}
109
+ * @see Design docs at {@link https://www.payfit.design/ Payfit.design}
110
+ * @see Developer docs at {@link https://unity-components.payfit.io/?path=/docs/forms-reference-passwordfield--docs unity-components.payfit.io}
111
+ */
112
+ declare const TanstackPasswordField: import('react').ForwardRefExoticComponent<TanstackPasswordFieldProps & import('react').RefAttributes<HTMLInputElement>>;
113
+ export { TanstackPasswordField };
@@ -0,0 +1,83 @@
1
+ import { jsxs as I, jsx as e } from "react/jsx-runtime";
2
+ import { forwardRef as B } from "react";
3
+ import { useIntl as R } from "react-intl";
4
+ import { useFieldContext as b } from "../../hooks/tanstack-form-context.js";
5
+ import { TanstackFormFeedbackText as j } from "../form-field/parts/TanstackFormFeedbackText.js";
6
+ import { TanstackFormHelperText as y } from "../form-field/parts/TanstackFormHelperText.js";
7
+ import { TanstackFormLabel as M } from "../form-field/parts/TanstackFormLabel.js";
8
+ import { TanstackFormField as V } from "../form-field/TanstackFormField.js";
9
+ import { PasswordFieldDetails as D } from "./parts/PasswordFieldDetails.js";
10
+ import { PasswordInput as H } from "./parts/PasswordInput.js";
11
+ function L({
12
+ label: r,
13
+ helperText: s,
14
+ rulesTitle: i,
15
+ rules: o,
16
+ contextualLink: l,
17
+ isRequired: n,
18
+ requiredVariant: m,
19
+ isLoading: d,
20
+ isDisabled: c,
21
+ isReadOnly: u,
22
+ showCapsLockWarning: f,
23
+ autoComplete: p,
24
+ onBlur: F,
25
+ onFocus: h,
26
+ onChange: T,
27
+ onClearButtonPress: k,
28
+ ...w
29
+ }, g) {
30
+ const P = R(), t = b(), x = t.state.meta.isTouched && !t.state.meta.isValid, v = o && o.length > 0, C = P.formatMessage({
31
+ id: "unity:component:password-field:rules-title",
32
+ defaultMessage: "Your password must have:"
33
+ });
34
+ return /* @__PURE__ */ I(V, { children: [
35
+ /* @__PURE__ */ e(
36
+ M,
37
+ {
38
+ requiredVariant: m,
39
+ isRequired: n,
40
+ children: r
41
+ }
42
+ ),
43
+ s && /* @__PURE__ */ e(y, { children: s }),
44
+ /* @__PURE__ */ e(
45
+ H,
46
+ {
47
+ ...w,
48
+ ref: g,
49
+ value: t.state.value,
50
+ onChange: (a) => {
51
+ t.handleChange(a.target.value), T?.(a);
52
+ },
53
+ onBlur: (a) => {
54
+ t.handleBlur(), F?.(a);
55
+ },
56
+ onFocus: h,
57
+ isLoading: d,
58
+ isDisabled: c,
59
+ isReadOnly: u,
60
+ isInvalid: x,
61
+ showCapsLockWarning: f,
62
+ autoComplete: p,
63
+ onClearButtonPress: () => {
64
+ t.setValue(""), k?.();
65
+ }
66
+ }
67
+ ),
68
+ /* @__PURE__ */ e(j, {}),
69
+ v && /* @__PURE__ */ e(
70
+ D,
71
+ {
72
+ title: i ?? C,
73
+ rules: o
74
+ }
75
+ ),
76
+ l
77
+ ] });
78
+ }
79
+ const N = B(L);
80
+ N.displayName = "TanstackPasswordField";
81
+ export {
82
+ N as TanstackPasswordField
83
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Hook to detect when Caps Lock is enabled
3
+ * @returns boolean indicating if Caps Lock is currently enabled
4
+ */
5
+ export declare function useCapsLock(): boolean;
@@ -0,0 +1,12 @@
1
+ import { useState as s, useCallback as r, useEffect as i } from "react";
2
+ function d() {
3
+ const [n, t] = s(!1), e = r((o) => {
4
+ t(o.getModifierState("CapsLock"));
5
+ }, []);
6
+ return i(() => (window.addEventListener("keydown", e), window.addEventListener("keyup", e), () => {
7
+ window.removeEventListener("keydown", e), window.removeEventListener("keyup", e);
8
+ }), [e]), n;
9
+ }
10
+ export {
11
+ d as useCapsLock
12
+ };
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { PasswordRule } from '../types.js';
3
+ interface PasswordFieldDetailsProps {
4
+ /** ID for the details element (used for aria-details) */
5
+ id?: string;
6
+ /** Title for the rules section */
7
+ title: ReactNode;
8
+ /** Array of password rules to display */
9
+ rules: PasswordRule[];
10
+ }
11
+ /**
12
+ * Displays the validation rules checklist for password requirements
13
+ * Renders a list of ValidationRuleItem components with a title
14
+ */
15
+ export declare function PasswordFieldDetails({ id, title, rules, }: PasswordFieldDetailsProps): import("react/jsx-runtime").JSX.Element | null;
16
+ export {};
@@ -0,0 +1,42 @@
1
+ import { jsxs as n, jsx as t } from "react/jsx-runtime";
2
+ import { uyTv as d } from "@payfit/unity-themes";
3
+ import { FormattedMessage as m } from "react-intl";
4
+ import { Text as l } from "../../text/Text.js";
5
+ import { ValidationRuleItem as u } from "./ValidationRuleItem.js";
6
+ const c = d({
7
+ slots: {
8
+ root: ["uy:flex uy:flex-col uy:gap-75"],
9
+ list: ["uy:list-none uy:p-0 uy:m-0 uy:contents"]
10
+ }
11
+ });
12
+ function v({
13
+ id: e,
14
+ title: a,
15
+ rules: o
16
+ }) {
17
+ if (o.length === 0)
18
+ return null;
19
+ const { root: i, list: r } = c();
20
+ return /* @__PURE__ */ n("div", { id: e, className: i(), children: [
21
+ /* @__PURE__ */ t(l, { variant: "h4", className: "uy:sr-only", children: a }),
22
+ /* @__PURE__ */ t(l, { variant: "bodySmall", color: "content.neutral", children: /* @__PURE__ */ t(
23
+ m,
24
+ {
25
+ id: "unity:component:password-field:rules-title",
26
+ defaultMessage: "Your password must have:"
27
+ }
28
+ ) }),
29
+ /* @__PURE__ */ t("ul", { className: r(), children: o.map((s) => /* @__PURE__ */ t(
30
+ u,
31
+ {
32
+ id: s.id,
33
+ label: s.label,
34
+ status: s.status
35
+ },
36
+ s.id
37
+ )) })
38
+ ] });
39
+ }
40
+ export {
41
+ v as PasswordFieldDetails
42
+ };
@@ -0,0 +1,25 @@
1
+ import { InputProps as AriaInputProps } from 'react-aria-components';
2
+ export interface PasswordInputProps extends Omit<AriaInputProps, 'type' | 'style' | 'className'> {
3
+ /** Whether the field is required */
4
+ isRequired?: boolean;
5
+ /** Whether the field is in an invalid state */
6
+ isInvalid?: boolean;
7
+ /** Whether the field is in a loading state */
8
+ isLoading?: boolean;
9
+ /** Whether the field is disabled */
10
+ isDisabled?: boolean;
11
+ /** Whether the field is read-only */
12
+ isReadOnly?: boolean;
13
+ /** Whether to show the caps lock warning (default: true) */
14
+ showCapsLockWarning?: boolean;
15
+ /** Autocomplete hint for password managers */
16
+ autoComplete?: 'new-password' | 'current-password';
17
+ /** Clear button press handler */
18
+ onClearButtonPress?: () => void;
19
+ }
20
+ /**
21
+ * PasswordInput component with visibility toggle and caps lock detection
22
+ * Based on the Unity Input component but specialized for password fields
23
+ */
24
+ declare const PasswordInput: import('react').ForwardRefExoticComponent<PasswordInputProps & import('react').RefAttributes<HTMLInputElement>>;
25
+ export { PasswordInput };
@@ -0,0 +1,188 @@
1
+ import { jsx as e, jsxs as p } from "react/jsx-runtime";
2
+ import { forwardRef as P, useState as m, useEffect as V } from "react";
3
+ import { Icon as b } from "@payfit/unity-icons";
4
+ import { uyTv as A } from "@payfit/unity-themes";
5
+ import { Input as B } from "react-aria-components";
6
+ import { useIntl as E } from "react-intl";
7
+ import { Actionable as T } from "../../actionable/Actionable.js";
8
+ import { useFieldA11yContext as j } from "../../form-field/TanstackFormField.context.js";
9
+ import { CircularIconButton as w } from "../../icon-button/CircularIconButton.js";
10
+ import { Spinner as L } from "../../spinner/Spinner.js";
11
+ import { Tooltip as z } from "../../tooltip/Tooltip.js";
12
+ import { useCapsLock as H } from "../hooks/use-caps-lock.js";
13
+ const R = A({
14
+ slots: {
15
+ base: "uy:flex uy:h-5.5 uy:sm:h-500 uy:border uy:border-solid uy:rounded-100 uy:sm:rounded-75 uy:focus-within:outline-none uy:focus-within:ring-2 uy:focus-within:ring-utility-focus-ring uy:focus-within:ring-offset-2 uy:active:border-border-form-active",
16
+ inputWrapper: "uy:flex uy:gap-50 uy:flex-grow uy:flex-nowrap uy:py-125 uy:sm:py-100 uy:px-150 uy:rounded-100 uy:sm:rounded-75 uy:max-w-full uy:justify-between",
17
+ input: "uy:w-full uy:flex-1 uy:outline-none uy:typography-body uy:placeholder:text-content-neutral-lowest uy:min-w-0 uy:max-w-full",
18
+ state: "uy:flex uy:gap-50 uy:items-center uy:shrink-0"
19
+ },
20
+ variants: {
21
+ isInvalid: {
22
+ true: {
23
+ base: "uy:border-border-form-error uy:bg-surface-form-error",
24
+ inputWrapper: "uy:bg-surface-form-error",
25
+ input: "uy:bg-surface-form-error",
26
+ state: "uy:text-content-form-error"
27
+ }
28
+ },
29
+ isReadOnly: {
30
+ true: {
31
+ base: "uy:border-border-form-disabled uy:bg-surface-form-disabled uy:cursor-not-allowed",
32
+ inputWrapper: "uy:bg-surface-form-disabled uy:cursor-not-allowed",
33
+ input: "uy:bg-surface-form-disabled uy:text-content-form-readonly uy:cursor-not-allowed"
34
+ }
35
+ },
36
+ isDisabled: {
37
+ true: {
38
+ base: "uy:border-border-form-disabled uy:bg-surface-form-disabled uy:cursor-not-allowed",
39
+ inputWrapper: "uy:bg-surface-form-disabled uy:text-content-form-disabled uy:cursor-not-allowed",
40
+ input: "uy:bg-surface-form-disabled uy:text-content-form-disabled uy:cursor-not-allowed"
41
+ }
42
+ }
43
+ },
44
+ compoundVariants: [
45
+ {
46
+ isInvalid: !1,
47
+ isDisabled: !1,
48
+ isReadOnly: !1,
49
+ className: {
50
+ base: "uy:border-border-form-enabled uy:bg-surface-form-enabled",
51
+ inputWrapper: "uy:bg-surface-form-enabled",
52
+ input: "uy:text-content-form-enabled uy:bg-surface-form-enabled",
53
+ state: "uy:text-content-neutral-disabled"
54
+ }
55
+ }
56
+ ]
57
+ }), q = P(
58
+ ({
59
+ isInvalid: l,
60
+ isLoading: i,
61
+ isDisabled: a,
62
+ isReadOnly: n,
63
+ showCapsLockWarning: g = !0,
64
+ autoComplete: d,
65
+ onClearButtonPress: h,
66
+ ...o
67
+ }, r) => {
68
+ const t = E(), [s, x] = m(!1), [c, f] = m(!1), y = j(), v = H();
69
+ V(() => {
70
+ c && r && "current" in r && r.current && (r.current.focus(), f(!1));
71
+ }, [c, r]);
72
+ const {
73
+ base: M,
74
+ inputWrapper: C,
75
+ input: I,
76
+ state: k
77
+ } = R({
78
+ isInvalid: !!l,
79
+ isReadOnly: !!n,
80
+ isDisabled: !!a
81
+ }), O = s ? "text" : "password", S = !(n || a), W = o.value && !i && !n && !a, F = d !== void 0, N = () => {
82
+ x((u) => !u), f(!0);
83
+ };
84
+ return delete o.isRequired, /* @__PURE__ */ e("div", { className: M(), children: /* @__PURE__ */ p("div", { className: C(), children: [
85
+ /* @__PURE__ */ e(
86
+ B,
87
+ {
88
+ "data-dd-privacy": "mask",
89
+ ...o,
90
+ ref: r,
91
+ id: o.id ?? y.inputId,
92
+ "aria-labelledby": y.labelId,
93
+ type: O,
94
+ autoComplete: F ? d : "off",
95
+ spellCheck: !1,
96
+ autoCapitalize: "off",
97
+ className: I(),
98
+ "aria-busy": i,
99
+ "aria-invalid": l,
100
+ readOnly: n,
101
+ disabled: a,
102
+ onFocus: (u) => {
103
+ o.onFocus?.(u);
104
+ },
105
+ onBlur: (u) => {
106
+ o.onBlur?.(u);
107
+ }
108
+ }
109
+ ),
110
+ /* @__PURE__ */ p("div", { className: k(), children: [
111
+ i && /* @__PURE__ */ e(
112
+ L,
113
+ {
114
+ color: "primary",
115
+ size: "small",
116
+ label: t.formatMessage({
117
+ id: "unity:component:common:loading:label",
118
+ defaultMessage: "Loading..."
119
+ })
120
+ }
121
+ ),
122
+ g && v && /* @__PURE__ */ e("div", { role: "status", "aria-live": "polite", children: /* @__PURE__ */ e(
123
+ z,
124
+ {
125
+ title: t.formatMessage({
126
+ id: "unity:component:password-field:caps-lock:tooltip",
127
+ defaultMessage: "Caps Lock is on"
128
+ }),
129
+ children: /* @__PURE__ */ e(T, { children: /* @__PURE__ */ e(
130
+ b,
131
+ {
132
+ src: "ArrowFatLineUpOutlined",
133
+ color: "content.neutral.low",
134
+ role: "presentation"
135
+ }
136
+ ) })
137
+ }
138
+ ) }),
139
+ l && /* @__PURE__ */ e(
140
+ b,
141
+ {
142
+ src: "WarningCircleOutlined",
143
+ color: "content.form.invalid",
144
+ alt: t.formatMessage({
145
+ id: "unity:component:form-field:form-input:error:alt",
146
+ defaultMessage: "Error"
147
+ })
148
+ }
149
+ ),
150
+ W && /* @__PURE__ */ e(
151
+ w,
152
+ {
153
+ title: t.formatMessage({
154
+ id: "unity:component:common:clear:title",
155
+ defaultMessage: "Clear"
156
+ }),
157
+ color: "content.neutral.low",
158
+ icon: "CloseOutlined",
159
+ onPress: () => {
160
+ h?.();
161
+ }
162
+ }
163
+ ),
164
+ S && /* @__PURE__ */ e(
165
+ w,
166
+ {
167
+ title: t.formatMessage({
168
+ id: s ? "unity:component:password-field:hide-password:title" : "unity:component:password-field:show-password:title",
169
+ defaultMessage: s ? "Hide password" : "Show password"
170
+ }),
171
+ "aria-label": t.formatMessage({
172
+ id: s ? "unity:component:password-field:hide-password:label" : "unity:component:password-field:show-password:label",
173
+ defaultMessage: s ? "Hide password" : "Show password"
174
+ }),
175
+ color: "content.neutral.low",
176
+ icon: s ? "EyeSlashOutlined" : "EyeOutlined",
177
+ onPress: N,
178
+ isDisabled: a
179
+ }
180
+ )
181
+ ] })
182
+ ] }) });
183
+ }
184
+ );
185
+ q.displayName = "PasswordInput";
186
+ export {
187
+ q as PasswordInput
188
+ };
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { PasswordRuleStatus } from '../types.js';
3
+ interface ValidationRuleItemProps {
4
+ /** Unique identifier for the rule */
5
+ id: string;
6
+ /** Label to display for the rule */
7
+ label: ReactNode;
8
+ /** Current status of the rule */
9
+ status: PasswordRuleStatus;
10
+ }
11
+ /**
12
+ * Individual validation rule item with status icon
13
+ * Displays a check circle icon that changes based on the rule's status
14
+ */
15
+ export declare function ValidationRuleItem({ id, label, status, }: ValidationRuleItemProps): import("react/jsx-runtime").JSX.Element;
16
+ export {};
@@ -0,0 +1,45 @@
1
+ import { jsx as r, jsxs as s } from "react/jsx-runtime";
2
+ import { useMemo as d } from "react";
3
+ import { Icon as a } from "@payfit/unity-icons";
4
+ import { uyTv as p } from "@payfit/unity-themes";
5
+ import { useIntl as f } from "react-intl";
6
+ const y = p({
7
+ slots: {
8
+ root: ["uy:flex uy:items-center uy:gap-50 uy:typography-body-small"],
9
+ label: ["uy:text-content-neutral"]
10
+ }
11
+ });
12
+ function k({
13
+ id: l,
14
+ label: e,
15
+ status: c
16
+ }) {
17
+ const o = f(), t = c === "checked", i = d(() => t ? /* @__PURE__ */ r(a, { src: "CheckCircleFilled", color: "content.success", size: 20 }) : /* @__PURE__ */ r(a, { src: "CheckCircleOutlined", color: "content.neutral", size: 20 }), [t]), n = t ? o.formatMessage({
18
+ id: "unity:component:password-field:rule-status:passed",
19
+ defaultMessage: "Passed"
20
+ }) : o.formatMessage({
21
+ id: "unity:component:password-field:rule-status:not-passed",
22
+ defaultMessage: "Not passed"
23
+ }), { root: u, label: m } = y();
24
+ return /* @__PURE__ */ s(
25
+ "li",
26
+ {
27
+ className: u(),
28
+ "aria-label": `${n}: ${typeof e == "string" ? e : ""}`,
29
+ children: [
30
+ i,
31
+ /* @__PURE__ */ s("span", { className: m(), children: [
32
+ /* @__PURE__ */ s("span", { className: "uy:sr-only", children: [
33
+ n,
34
+ ": "
35
+ ] }),
36
+ e
37
+ ] })
38
+ ]
39
+ },
40
+ l
41
+ );
42
+ }
43
+ export {
44
+ k as ValidationRuleItem
45
+ };
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ /** Status of a password rule - controlled by consumer */
3
+ export type PasswordRuleStatus = 'unchecked' | 'checked';
4
+ /** A display-only rule item for the password requirements list */
5
+ export interface PasswordRule {
6
+ /** Unique identifier for the rule */
7
+ id: string;
8
+ /** Label displayed in the rules list */
9
+ label: ReactNode;
10
+ /** Current status - controlled by the consumer based on their validation logic */
11
+ status: PasswordRuleStatus;
12
+ }
@@ -1,4 +1,4 @@
1
- import { jsxs as t, jsx as e } from "react/jsx-runtime";
1
+ import { jsxs as o, jsx as e } from "react/jsx-runtime";
2
2
  import { forwardRef as f } from "react";
3
3
  import { uyTv as m } from "@payfit/unity-themes";
4
4
  import { Button as b, SelectValue as p } from "react-aria-components";
@@ -53,13 +53,13 @@ const x = m({
53
53
  isReadOnly: !1
54
54
  }
55
55
  }), h = f(
56
- ({ isDisabled: r, isInvalid: o, isReadOnly: s, isOpen: u }, l) => {
56
+ ({ isDisabled: r, isInvalid: t, isReadOnly: s, isOpen: u }, l) => {
57
57
  const n = v(), { base: i, selectValue: d, iconWrapper: y, icon: c } = x({
58
58
  isDisabled: r,
59
- isInvalid: o,
59
+ isInvalid: t,
60
60
  isReadOnly: s
61
61
  });
62
- return /* @__PURE__ */ t(
62
+ return /* @__PURE__ */ o(
63
63
  b,
64
64
  {
65
65
  "data-dd-privacy": "mask",
@@ -68,9 +68,9 @@ const x = m({
68
68
  isDisabled: r,
69
69
  "data-unity-slot": "select-button",
70
70
  children: [
71
- /* @__PURE__ */ e(p, { className: d() }),
72
- /* @__PURE__ */ t("div", { className: y(), children: [
73
- o && /* @__PURE__ */ e(
71
+ /* @__PURE__ */ e(p, { className: d(), translate: "no" }),
72
+ /* @__PURE__ */ o("div", { className: y(), children: [
73
+ t && /* @__PURE__ */ e(
74
74
  a,
75
75
  {
76
76
  src: "WarningCircleOutlined",