A controlled React component for managing a list of allowed domains, supporting dynamic addition/removal, optional validation, and inline error display. ## Key Components ### `AllowedDomainsInputProps` | Prop | Type | Description | |---|---|---| | `value` | `string[]` | Controlled list of current domains | | `onChange` | `(domains: string[]) => void` | Callback fired when the domain list changes | | `onValidate` | `(domain: string) => { valid: boolean; error?: string; cleanedDomain?: string }` | Optional custom validator; can return a sanitized domain | | `label` | `string` | Field label (default: `"Allowed Domains"`) | | `placeholder` | `string` | Input placeholder (default: `"example.com"`) | | `disabled` | `boolean` | Disables all interactions | | `error` | `string \| null` | External error message | | `helperText` | `string` | Assistive text shown when no error is present | | `className` | `string` | Additional CSS classes | ### `AllowedDomainsInput` A `forwardRef` component that renders: - Existing domains as read-only inputs with individual remove (`X`) buttons - A text input for entering new domains (supports `Enter` key to submit) - An **Add Domain** button with a `PlusCircle` icon - Inline error and helper text display Duplicate domains are silently rejected. Local validation errors are cleared on each input change. ## Usage Example ```typescript import { AllowedDomainsInput } from "@/components/ui/allowed-domains-input" import { useState } from "react" function DomainSettings() { const [domains, setDomains] = useState(["flamingo.run"]) const validateDomain = (domain: string) => { const cleaned = domain.toLowerCase().replace(/^https?:\/\//, "") const isValid = /^[a-z0-9.-]+\.[a-z]{2,}$/.test(cleaned) return { valid: isValid, error: isValid ? undefined : "Enter a valid domain (e.g. example.com)", cleanedDomain: cleaned, } } return ( ) } ``` ## Source [`allowed-domains-input.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/src/components/ui/allowed-domains-input.tsx)