From 334f8814373d132035309d2620a11c545688e95d Mon Sep 17 00:00:00 2001 From: masnwilliams <43387599+masnwilliams@users.noreply.github.com> Date: Sat, 1 Aug 2026 15:52:50 +0000 Subject: [PATCH] Show notice for rejected fields --- .changeset/replace-existing-field-notice.md | 5 ++ .../src/appearance/types.ts | 2 + .../src/components/UnifiedAuthForm.tsx | 5 ++ packages/managed-auth-react/src/lib/types.ts | 2 + .../src/localization/defaults.ts | 2 + .../src/localization/types.ts | 1 + .../src/session/state.test.ts | 61 +++++++++++++++++++ .../managed-auth-react/src/session/state.ts | 28 ++++++--- .../managed-auth-react/src/styles/styles.css | 6 ++ 9 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 .changeset/replace-existing-field-notice.md diff --git a/.changeset/replace-existing-field-notice.md b/.changeset/replace-existing-field-notice.md new file mode 100644 index 0000000..60f1153 --- /dev/null +++ b/.changeset/replace-existing-field-notice.md @@ -0,0 +1,5 @@ +--- +"@onkernel/managed-auth-react": minor +--- + +Show a notice when a canonical field has `reason: "rejected"`. Adds the `fieldRejectedNotice` label and the `inputRejectedNotice` appearance slot. diff --git a/packages/managed-auth-react/src/appearance/types.ts b/packages/managed-auth-react/src/appearance/types.ts index 16eb621..4db0796 100644 --- a/packages/managed-auth-react/src/appearance/types.ts +++ b/packages/managed-auth-react/src/appearance/types.ts @@ -71,6 +71,8 @@ export interface AppearanceElements { input?: ElementValue; /** Small hint text under an input. */ inputHint?: ElementValue; + /** Notice under an input whose saved value was rejected. */ + inputRejectedNotice?: ElementValue; /** Password show/hide toggle button. */ passwordToggle?: ElementValue; /** All buttons — base. */ diff --git a/packages/managed-auth-react/src/components/UnifiedAuthForm.tsx b/packages/managed-auth-react/src/components/UnifiedAuthForm.tsx index 49395f0..0306f7f 100644 --- a/packages/managed-auth-react/src/components/UnifiedAuthForm.tsx +++ b/packages/managed-auth-react/src/components/UnifiedAuthForm.tsx @@ -300,6 +300,11 @@ export function UnifiedAuthForm({ } /> )} + {field.reason === "rejected" && ( +
+ {l.fieldRejectedNotice} +
+ )} {field.hint && ({field.hint}
)} diff --git a/packages/managed-auth-react/src/lib/types.ts b/packages/managed-auth-react/src/lib/types.ts index c78e79d..681d1ec 100644 --- a/packages/managed-auth-react/src/lib/types.ts +++ b/packages/managed-auth-react/src/lib/types.ts @@ -35,6 +35,7 @@ export interface DiscoveredField { type: "text" | "email" | "password" | "tel" | "code" | "totp"; placeholder?: string; required?: boolean; + reason?: "missing" | "rejected"; hint?: string; linked_mfa_type?: MFAType; } @@ -73,6 +74,7 @@ export interface ManagedAuthField { | "text"; label?: string; required?: boolean; + reason: "missing" | "rejected"; hint?: string; observed_selector?: string | null; } diff --git a/packages/managed-auth-react/src/localization/defaults.ts b/packages/managed-auth-react/src/localization/defaults.ts index 01ccebc..9dddebc 100644 --- a/packages/managed-auth-react/src/localization/defaults.ts +++ b/packages/managed-auth-react/src/localization/defaults.ts @@ -42,6 +42,8 @@ export const DEFAULT_LOCALIZATION: Localizer = { orDivider: "or", passwordShow: "Show password", passwordHide: "Hide password", + fieldRejectedNotice: + "The saved value was rejected. Enter a new one to continue.", credentialSafetyNotice: "Your credentials are encrypted and sent directly from your browser. They are never shared with anyone or any LLM.", mfaTypeLabels: { diff --git a/packages/managed-auth-react/src/localization/types.ts b/packages/managed-auth-react/src/localization/types.ts index 1c01c71..73d28a7 100644 --- a/packages/managed-auth-react/src/localization/types.ts +++ b/packages/managed-auth-react/src/localization/types.ts @@ -39,6 +39,7 @@ export interface Localization { orDivider?: string; passwordShow?: string; passwordHide?: string; + fieldRejectedNotice?: string; credentialSafetyNotice?: string; /** MFA type labels. */ mfaTypeLabels?: Partial