Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snippet type fix, lint fix, code refactor and cleanup #53

Merged
merged 10 commits into from
Nov 16, 2024
4 changes: 2 additions & 2 deletions components/ui/phone-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";

type PhoneInputProps = Omit<
React.InputHTMLAttributes<HTMLInputElement>,
"onChange" | "value"
React.ComponentProps<"input">,
"onChange" | "value" | "ref"
> &
Omit<RPNInput.Props<typeof RPNInput.default>, "onChange"> & {
onChange?: (value: RPNInput.Value) => void;
Expand Down
95 changes: 49 additions & 46 deletions content/snippets/phone-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import { cn } from "@/lib/utils";
import { ScrollArea } from "./scroll-area";

type PhoneInputProps = Omit<
React.InputHTMLAttributes<HTMLInputElement>,
"onChange" | "value"
React.ComponentProps<"input">,
"onChange" | "value" | "ref"
> &
Omit<RPNInput.Props<typeof RPNInput.default>, "onChange"> & {
onChange?: (value: RPNInput.Value) => void;
Expand All @@ -59,7 +59,7 @@ const PhoneInput: React.ForwardRefExoticComponent<PhoneInputProps> =
*
* @param {E164Number | undefined} value - The entered value
*/
onChange={(value) => onChange?.(value || "")}
onChange={(value) => onChange?.(value || ("" as RPNInput.Value))}
{...props}
/>
);
Expand All @@ -78,41 +78,37 @@ const InputComponent = React.forwardRef<HTMLInputElement, InputProps>(
);
InputComponent.displayName = "InputComponent";

type CountrySelectOption = { label: string; value: RPNInput.Country };
type CountryEntry = { label: string; value: RPNInput.Country | undefined };

type CountrySelectProps = {
disabled?: boolean;
value: RPNInput.Country;
onChange: (value: RPNInput.Country) => void;
options: CountrySelectOption[];
options: CountryEntry[];
onChange: (country: RPNInput.Country) => void;
};

const CountrySelect = ({
disabled,
value,
value: selectedCountry,
options: countryList,
onChange,
options,
}: CountrySelectProps) => {
const handleSelect = React.useCallback(
(country: RPNInput.Country) => {
onChange(country);
},
[onChange],
);

return (
<Popover>
<PopoverTrigger asChild>
<Button
type="button"
variant={"outline"}
className={cn("flex gap-1 rounded-e-none rounded-s-lg px-3")}
variant="outline"
className="flex gap-1 rounded-e-none rounded-s-lg px-3"
disabled={disabled}
>
<FlagComponent country={value} countryName={value} />
<FlagComponent
country={selectedCountry}
countryName={selectedCountry}
/>
<ChevronsUpDown
className={cn(
"-mr-2 h-4 w-4 opacity-50",
"-mr-2 size-4 opacity-50",
disabled ? "hidden" : "opacity-100",
)}
/>
Expand All @@ -125,32 +121,17 @@ const CountrySelect = ({
<ScrollArea className="h-72">
<CommandEmpty>No country found.</CommandEmpty>
<CommandGroup>
{options
.filter((x) => x.value)
.map((option) => (
<CommandItem
className="gap-2"
key={option.value}
onSelect={() => handleSelect(option.value)}
>
<FlagComponent
country={option.value}
countryName={option.label}
/>
<span className="flex-1 text-sm">{option.label}</span>
{option.value && (
<span className="text-foreground/50 text-sm">
{`+${RPNInput.getCountryCallingCode(option.value)}`}
</span>
)}
<CheckIcon
className={cn(
"ml-auto h-4 w-4",
option.value === value ? "opacity-100" : "opacity-0",
)}
/>
</CommandItem>
))}
{countryList.map(({ value, label }) =>
value ? (
<CountrySelectOption
key={value}
country={value}
countryName={label}
selectedCountry={selectedCountry}
onChange={onChange}
/>
) : null,
)}
</CommandGroup>
</ScrollArea>
</CommandList>
Expand All @@ -160,6 +141,29 @@ const CountrySelect = ({
);
};

interface CountrySelectOptionProps extends RPNInput.FlagProps {
selectedCountry: RPNInput.Country;
onChange: (country: RPNInput.Country) => void;
}

const CountrySelectOption = ({
country,
countryName,
selectedCountry,
onChange,
}: CountrySelectOptionProps) => {
return (
<CommandItem className="gap-2" onSelect={() => onChange(country)}>
<FlagComponent country={country} countryName={countryName} />
<span className="flex-1 text-sm">{countryName}</span>
<span className="text-foreground/50 text-sm">{`+${RPNInput.getCountryCallingCode(country)}`}</span>
<CheckIcon
className={`ml-auto size-4 ${country === selectedCountry ? "opacity-100" : "opacity-0"}`}
/>
</CommandItem>
);
};

const FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => {
const Flag = flags[country];

Expand All @@ -169,7 +173,6 @@ const FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => {
</span>
);
};
FlagComponent.displayName = "FlagComponent";

export { PhoneInput };
```
Loading