fix(dashboard): replace native select Element in CountrySelect & ProvinceSelect with Select(Medusa UI). (#13521)
* fix: replace CountrySelect fallback with Medusa Select * Country Select Component Fix to use Medusa UI Select Component * added Change set * using the props supported by the Select * value should be lowercased if passed from the pareant component * fix province Select with medusa UI select and added change set * bug fix the province with providing --------- Co-authored-by: Aryan Patel <21cs038@charusat.edu.in> Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
This commit is contained in:
co-authored by
Aryan Patel
William Bouchard
parent
c54c5ed6de
commit
a1c56d29d0
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/dashboard": patch
|
||||
---
|
||||
|
||||
fix(dashboard):replace native select Element in CountrySelect & ProvinceSelect with Select(Medusa UI).
|
||||
@@ -4,75 +4,50 @@ import {
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
} from "react"
|
||||
|
||||
import { TrianglesMini } from "@medusajs/icons"
|
||||
import { clx } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { countries } from "../../../lib/data/countries"
|
||||
import { Select } from "@medusajs/ui"
|
||||
|
||||
export const CountrySelect = forwardRef<
|
||||
HTMLSelectElement,
|
||||
ComponentPropsWithoutRef<"select"> & {
|
||||
HTMLButtonElement,
|
||||
ComponentPropsWithoutRef<typeof Select> & {
|
||||
placeholder?: string
|
||||
value?: string
|
||||
defaultValue?: string
|
||||
onChange?: (value: string) => void
|
||||
}
|
||||
>(
|
||||
(
|
||||
{ className, disabled, placeholder, value, defaultValue, ...props },
|
||||
ref
|
||||
) => {
|
||||
const { t } = useTranslation()
|
||||
const innerRef = useRef<HTMLSelectElement>(null)
|
||||
>(({ disabled, placeholder, defaultValue, onChange, ...field }, ref) => {
|
||||
const { t } = useTranslation()
|
||||
const innerRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
useImperativeHandle(ref, () => innerRef.current as HTMLSelectElement)
|
||||
useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement)
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<Select
|
||||
{...field}
|
||||
value={field.value ? field.value?.toLowerCase() : undefined}
|
||||
onValueChange={onChange}
|
||||
defaultValue={defaultValue ? defaultValue.toLowerCase() : undefined}
|
||||
disabled={disabled}
|
||||
>
|
||||
<Select.Trigger ref={innerRef} className="w-full">
|
||||
<Select.Value
|
||||
placeholder={placeholder || t("fields.selectCountry")}
|
||||
/>
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{countries.map((country) => (
|
||||
<Select.Item
|
||||
key={country.iso_2}
|
||||
value={country.iso_2.toLowerCase()}
|
||||
>
|
||||
{country.display_name}
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
const isPlaceholder = innerRef.current?.value === ""
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<TrianglesMini
|
||||
className={clx(
|
||||
"text-ui-fg-muted transition-fg pointer-events-none absolute end-2 top-1/2 -translate-y-1/2",
|
||||
{
|
||||
"text-ui-fg-disabled": disabled,
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<select
|
||||
value={value !== undefined ? value.toLowerCase() : undefined}
|
||||
defaultValue={defaultValue ? defaultValue.toLowerCase() : undefined}
|
||||
disabled={disabled}
|
||||
className={clx(
|
||||
"bg-ui-bg-field shadow-buttons-neutral transition-fg txt-compact-small flex w-full select-none appearance-none items-center justify-between rounded-md px-2 py-1.5 outline-none",
|
||||
"placeholder:text-ui-fg-muted text-ui-fg-base",
|
||||
"hover:bg-ui-bg-field-hover",
|
||||
"focus-visible:shadow-borders-interactive-with-active data-[state=open]:!shadow-borders-interactive-with-active",
|
||||
"aria-[invalid=true]:border-ui-border-error aria-[invalid=true]:shadow-borders-error",
|
||||
"invalid::border-ui-border-error invalid:shadow-borders-error",
|
||||
"disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
|
||||
{
|
||||
"text-ui-fg-muted": isPlaceholder,
|
||||
},
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
ref={innerRef}
|
||||
>
|
||||
{/* Add an empty option so the first option is preselected */}
|
||||
<option value="" disabled className="text-ui-fg-muted">
|
||||
{placeholder || t("fields.selectCountry")}
|
||||
</option>
|
||||
{countries.map((country) => {
|
||||
return (
|
||||
<option key={country.iso_2} value={country.iso_2.toLowerCase()}>
|
||||
{country.display_name}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
CountrySelect.displayName = "CountrySelect"
|
||||
|
||||
+42
-62
@@ -4,47 +4,36 @@ import {
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
} from "react"
|
||||
|
||||
import { TrianglesMini } from "@medusajs/icons"
|
||||
import { clx } from "@medusajs/ui"
|
||||
import { Select } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { getCountryProvinceObjectByIso2 } from "../../../lib/data/country-states"
|
||||
|
||||
interface ProvinceSelectProps extends ComponentPropsWithoutRef<"select"> {
|
||||
/**
|
||||
* ISO 3166-1 alpha-2 country code
|
||||
*/
|
||||
country_code: string
|
||||
/**
|
||||
* Whether to use the ISO 3166-1 alpha-2 code or the name of the province as the value
|
||||
*
|
||||
* @default "iso_2"
|
||||
*/
|
||||
valueAs?: "iso_2" | "name"
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
export const ProvinceSelect = forwardRef<
|
||||
HTMLSelectElement,
|
||||
ProvinceSelectProps
|
||||
HTMLButtonElement,
|
||||
ComponentPropsWithoutRef<typeof Select> & {
|
||||
placeholder?: string
|
||||
defaultValue?: string
|
||||
country_code: string
|
||||
valueAs?: "iso_2" | "name"
|
||||
onChange?: (value: string) => void
|
||||
}
|
||||
>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
disabled,
|
||||
placeholder,
|
||||
defaultValue,
|
||||
country_code,
|
||||
valueAs = "iso_2",
|
||||
...props
|
||||
onChange,
|
||||
...field
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const { t } = useTranslation()
|
||||
const innerRef = useRef<HTMLSelectElement>(null)
|
||||
const innerRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
useImperativeHandle(ref, () => innerRef.current as HTMLSelectElement)
|
||||
|
||||
const isPlaceholder = innerRef.current?.value === ""
|
||||
useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement)
|
||||
|
||||
const provinceObject = getCountryProvinceObjectByIso2(country_code)
|
||||
|
||||
@@ -55,9 +44,12 @@ export const ProvinceSelect = forwardRef<
|
||||
const options = Object.entries(provinceObject?.options ?? {}).map(
|
||||
([iso2, name]) => {
|
||||
return (
|
||||
<option key={iso2} value={valueAs === "iso_2" ? iso2 : name}>
|
||||
<Select.Item
|
||||
key={iso2}
|
||||
value={valueAs === "iso_2" ? iso2.toLowerCase() : name}
|
||||
>
|
||||
{name}
|
||||
</option>
|
||||
</Select.Item>
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -66,46 +58,34 @@ export const ProvinceSelect = forwardRef<
|
||||
? t(`taxRegions.fields.sublevels.placeholders.${provinceObject.type}`)
|
||||
: ""
|
||||
|
||||
const placeholderOption = provinceObject ? (
|
||||
<option value="" disabled className="text-ui-fg-muted">
|
||||
{placeholder || placeholderText}
|
||||
</option>
|
||||
) : null
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<TrianglesMini
|
||||
className={clx(
|
||||
"text-ui-fg-muted transition-fg pointer-events-none absolute end-2 top-1/2 -translate-y-1/2",
|
||||
{
|
||||
"text-ui-fg-disabled": disabled,
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<select
|
||||
<Select
|
||||
{...field}
|
||||
value={
|
||||
field.value
|
||||
? valueAs === "iso_2"
|
||||
? field.value.toLowerCase()
|
||||
: field.value
|
||||
: undefined
|
||||
}
|
||||
defaultValue={
|
||||
defaultValue
|
||||
? valueAs === "iso_2"
|
||||
? defaultValue.toLowerCase()
|
||||
: defaultValue
|
||||
: undefined
|
||||
}
|
||||
onValueChange={onChange}
|
||||
disabled={disabled}
|
||||
className={clx(
|
||||
"bg-ui-bg-field shadow-buttons-neutral transition-fg txt-compact-small flex w-full select-none appearance-none items-center justify-between rounded-md px-2 py-1.5 outline-none",
|
||||
"placeholder:text-ui-fg-muted text-ui-fg-base",
|
||||
"hover:bg-ui-bg-field-hover",
|
||||
"focus-visible:shadow-borders-interactive-with-active data-[state=open]:!shadow-borders-interactive-with-active",
|
||||
"aria-[invalid=true]:border-ui-border-error aria-[invalid=true]:shadow-borders-error",
|
||||
"invalid::border-ui-border-error invalid:shadow-borders-error",
|
||||
"disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
|
||||
{
|
||||
"text-ui-fg-muted": isPlaceholder,
|
||||
},
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
ref={innerRef}
|
||||
>
|
||||
{/* Add an empty option so the first option is preselected */}
|
||||
{placeholderOption}
|
||||
{options}
|
||||
</select>
|
||||
<Select.Trigger ref={innerRef} className="w-full">
|
||||
<Select.Value placeholder={placeholder || placeholderText} />
|
||||
</Select.Trigger>
|
||||
<Select.Content>{options}</Select.Content>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
ProvinceSelect.displayName = "CountrySelect"
|
||||
ProvinceSelect.displayName = "ProvinceSelect"
|
||||
|
||||
+1
-2
@@ -4,12 +4,11 @@ import { Button, Input, toast } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import * as zod from "zod"
|
||||
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import { CountrySelect } from "../../../../../components/inputs/country-select"
|
||||
import { RouteDrawer, useRouteModal } from "../../../../../components/modals"
|
||||
import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
|
||||
import { useUpdateStockLocation } from "../../../../../hooks/api/stock-locations"
|
||||
import { CountrySelect } from "../../../../../components/inputs/country-select/country-select"
|
||||
|
||||
type EditLocationFormProps = {
|
||||
location: HttpTypes.AdminStockLocation
|
||||
|
||||
Reference in New Issue
Block a user