nextuiq
Version:
NextUIQ is a modern, lightweight, and developer-friendly UI component library for React and Next.js. Built with TypeScript and Tailwind CSS, it offers customizable, accessible, and performance-optimized components with built-in dark mode, theme customizat
132 lines (129 loc) • 4.93 kB
JavaScript
import { j as jsxRuntimeExports } from './index46.mjs';
import React__default, { useState, useMemo, useCallback, useId } from 'react';
const PhoneInputComponent = ({
countries,
placeholder = "+1 (555) 000-0000",
onChange,
selectPosition = "start",
id,
name,
required = false,
disabled = false,
"aria-label": ariaLabel,
"aria-describedby": ariaDescribedby
}) => {
const [selectedCountry, setSelectedCountry] = useState("US");
const [phoneNumber, setPhoneNumber] = useState("+1");
const countryMap = useMemo(
() => countries.reduce((acc, country) => ({
...acc,
[country.code]: country
}), {}),
[countries]
);
const handleCountryChange = useCallback((e) => {
const newCountry = e.target.value;
setSelectedCountry(newCountry);
const country = countryMap[newCountry];
setPhoneNumber(country?.code || "+1");
onChange?.(country?.code || "+1");
}, [countryMap, onChange]);
const uniqueId = useId();
const inputId = id || uniqueId;
const selectId = `${inputId}-country`;
const handlePhoneNumberChange = useCallback((e) => {
const newPhoneNumber = e.target.value;
setPhoneNumber(newPhoneNumber);
onChange?.(newPhoneNumber);
}, [onChange]);
const SelectComponent = useCallback(({ position }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `absolute ${position === "end" ? "right-0" : ""}`, children: [
/* @__PURE__ */ jsxRuntimeExports.jsx(
"select",
{
id: selectId,
value: selectedCountry,
onChange: handleCountryChange,
disabled,
required,
"aria-label": "Select country code",
className: `appearance-none bg-none ${position === "start" ? "rounded-l-lg border-r" : "rounded-r-lg border-l"} border-0 border-[oklch(var(--theme-border))] bg-transparent py-3 pl-3.5 pr-8
text-[oklch(var(--theme-foreground))]
focus:border-[oklch(var(--theme-ring))]
focus:outline-none focus:ring-2
focus:ring-[oklch(var(--theme-ring))]`,
children: countries.map((country) => /* @__PURE__ */ jsxRuntimeExports.jsx(
"option",
{
value: country.code,
className: "text-[oklch(var(--theme-foreground))] bg-[oklch(var(--theme-background))]",
children: country.code
},
country.code
))
}
),
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0 flex items-center text-[oklch(var(--theme-muted-foreground))] pointer-events-none right-3", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
"svg",
{
className: "stroke-current",
width: "20",
height: "20",
viewBox: "0 0 20 20",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
"aria-hidden": "true",
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
"path",
{
d: "M4.79175 7.396L10.0001 12.6043L15.2084 7.396",
stroke: "currentColor",
strokeWidth: "1.5",
strokeLinecap: "round",
strokeLinejoin: "round"
}
)
}
) })
] }), [selectId, selectedCountry, handleCountryChange, disabled, required, countries]);
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
"div",
{
className: "relative flex",
role: "group",
"aria-labelledby": ariaLabel ? void 0 : inputId,
children: [
selectPosition === "start" && /* @__PURE__ */ jsxRuntimeExports.jsx(SelectComponent, { position: "start" }),
/* @__PURE__ */ jsxRuntimeExports.jsx(
"input",
{
type: "tel",
id: inputId,
name,
value: phoneNumber,
onChange: handlePhoneNumberChange,
placeholder,
required,
disabled,
"aria-label": ariaLabel || "Phone number",
"aria-describedby": ariaDescribedby,
inputMode: "tel",
autoComplete: "tel",
className: `h-11 w-full ${selectPosition === "start" ? "pl-[84px]" : "pr-[84px]"} rounded-lg border border-[oklch(var(--theme-border))]
bg-[oklch(var(--theme-background))] py-3 px-4 text-sm
text-[oklch(var(--theme-foreground))] shadow-sm
placeholder:text-[oklch(var(--theme-muted-foreground))]
focus:border-[oklch(var(--theme-ring))]
focus:outline-none focus:ring-2
focus:ring-[oklch(var(--theme-ring))]
disabled:cursor-not-allowed disabled:opacity-50`
}
),
selectPosition === "end" && /* @__PURE__ */ jsxRuntimeExports.jsx(SelectComponent, { position: "end" })
]
}
);
};
const MemoizedPhoneInput = React__default.memo(PhoneInputComponent);
MemoizedPhoneInput.displayName = "PhoneInput";
const PhoneInput = MemoizedPhoneInput;
export { PhoneInput };