Skip to content

Commit

Permalink
fix: snippet type, linting, and code refactor (#53)
Browse files Browse the repository at this point in the history
* remove unnecessary filter
* remove unnecessary displayName assignment
* remove another unnecessary check
* use tailwind size instead of h and w + format
* some refactor and cleanup
* fix: update PhoneInputProps to omit "ref" in type definition

---------

Co-Authored-By: omeralpi <omeralpi@icloud.com>
  • Loading branch information
ahkhanjani and omeralpi committed Nov 16, 2024
1 parent 499d319 commit 711ea92
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 92 deletions.
97 changes: 50 additions & 47 deletions components/ui/phone-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { ScrollArea } from "@/components/ui/scroll-area";

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 @@ -53,7 +53,7 @@ const PhoneInput: React.ForwardRefExoticComponent<PhoneInputProps> =
*
* @param {E164Number | undefined} value - The entered value
*/
onChange={(value) => onChange?.(value || ("" as RPNInput.Value))}
onChange={(value) => onChange?.(value || "")}
{...props}
/>
);
Expand All @@ -72,41 +72,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 @@ -119,32 +115,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-sm text-foreground/50">
{`+${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 @@ -154,6 +135,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-sm text-foreground/50">{`+${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 @@ -163,6 +167,5 @@ const FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => {
</span>
);
};
FlagComponent.displayName = "FlagComponent";

export { PhoneInput };
93 changes: 48 additions & 45 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 Down Expand Up @@ -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 };
```

0 comments on commit 711ea92

Please sign in to comment.