feat(WEB-170): edit profile view
This commit is contained in:
109
components/TempDesignSystem/Form/Country/index.tsx
Normal file
109
components/TempDesignSystem/Form/Country/index.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
"use client"
|
||||
import { useController, useFormContext } from "react-hook-form"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
|
||||
import { _ } from "@/lib/translation"
|
||||
import { countries } from "./countries"
|
||||
|
||||
import {
|
||||
Button,
|
||||
ComboBox,
|
||||
FieldError,
|
||||
Input,
|
||||
ListBox,
|
||||
ListBoxItem,
|
||||
Popover,
|
||||
type Key,
|
||||
} from "react-aria-components"
|
||||
import { ErrorMessage } from "@hookform/error-message"
|
||||
import SelectChevron from "../SelectChevron"
|
||||
|
||||
import styles from "./country.module.css"
|
||||
|
||||
import type { CountryProps } from "./country"
|
||||
|
||||
export default function CountrySelect({
|
||||
name = "country",
|
||||
placeholder = "Select a country",
|
||||
registerOptions,
|
||||
}: CountryProps) {
|
||||
const divRef = useRef<HTMLDivElement>(null)
|
||||
const [divElement, setDivElement] = useState(divRef.current)
|
||||
const { control, setValue } = useFormContext()
|
||||
const { field } = useController({
|
||||
control,
|
||||
name,
|
||||
rules: registerOptions,
|
||||
})
|
||||
const [selectedKey, setSelectedKey] = useState(() => {
|
||||
if (field.value) {
|
||||
const selected = countries.find(
|
||||
(country) =>
|
||||
country.name === field.value || country.code === field.value
|
||||
)
|
||||
if (selected) {
|
||||
return selected.name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
})
|
||||
|
||||
function handleChange(country: Key) {
|
||||
setSelectedKey(String(country))
|
||||
setValue(name, country)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (divRef.current) {
|
||||
setDivElement(divRef.current)
|
||||
}
|
||||
}, [divRef.current])
|
||||
|
||||
return (
|
||||
<div className={styles.container} ref={divRef}>
|
||||
<ComboBox
|
||||
className={styles.select}
|
||||
isRequired={!!registerOptions?.required}
|
||||
name={field.name}
|
||||
onBlur={field.onBlur}
|
||||
onSelectionChange={handleChange}
|
||||
ref={field.ref}
|
||||
selectedKey={selectedKey}
|
||||
>
|
||||
<div className={styles.comboBoxContainer}>
|
||||
<Input className={styles.input} placeholder={_(placeholder)} />
|
||||
<Button className={styles.button}>
|
||||
<SelectChevron />
|
||||
</Button>
|
||||
</div>
|
||||
<FieldError>
|
||||
<ErrorMessage name={name} />
|
||||
</FieldError>
|
||||
<Popover
|
||||
className={styles.popover}
|
||||
placement="bottom"
|
||||
shouldFlip={false}
|
||||
/**
|
||||
* react-aria uses portals to render Popover in body
|
||||
* unless otherwise specified. We need it to be contained
|
||||
* by this component to both access css variables assigned
|
||||
* on the container as well as to not overflow it at any time.
|
||||
*/
|
||||
UNSTABLE_portalContainer={divElement ?? undefined}
|
||||
>
|
||||
<ListBox>
|
||||
{countries.map((country, idx) => (
|
||||
<ListBoxItem
|
||||
className={styles.listBoxItem}
|
||||
id={country.name}
|
||||
key={`${country.code}-${idx}`}
|
||||
>
|
||||
{country.name}
|
||||
</ListBoxItem>
|
||||
))}
|
||||
</ListBox>
|
||||
</Popover>
|
||||
</ComboBox>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user