import { TextInput } from "./TextInput"; export function IPInput(p: { label: string; editable: boolean; value?: string; onValueChange?: (newVal: string | undefined) => void; version: 4 | 6; }): React.ReactElement { const { onValueChange, ...props } = p; return ( { onValueChange?.(p.version === 4 ? sanitizeIpV4(v) : sanitizeIpV6(v)); }} {...props} /> ); } function sanitizeIpV4(s: string | undefined): string | undefined { if (s === "" || s === undefined) return s; let split = s.split("."); if (split.length > 4) split.splice(4); let needAnotherIteration = false; const res = split .map((v) => { if (v === "") return ""; const num = Number(v); if (isNaN(num) || num < 0) return "0"; if (num > 255) { needAnotherIteration = true; return v.slice(0, 2) + "." + v.slice(2); } return num.toString(); }) .join("."); return needAnotherIteration ? sanitizeIpV4(res) : res; } function sanitizeIpV6(s: string | undefined): string | undefined { if (s === "" || s === undefined) return s; const split = s.split(":"); if (split.length > 8) split.splice(8); let needAnotherIteration = false; let res = split .map((e) => { if (e === "") return e; const num = parseInt(e, 16); if (isNaN(num)) return "0"; let s = num.toString(16); if (num > 0xffff) { needAnotherIteration = true; return s.slice(0, 4) + ":" + s.slice(4); } return s; }) .join(":"); const firstIndex = res.indexOf("::"); let nextIndex = res.lastIndexOf("::"); while (nextIndex !== firstIndex) { res = res.slice(0, nextIndex) + res.slice(nextIndex + 1); nextIndex = res.lastIndexOf("::"); } return needAnotherIteration ? sanitizeIpV6(res) : res; }