feat(dashboard,types,js-sdk,ui): Tax Regions UI (#7935)

This commit is contained in:
Kasper Fabricius Kristensen
2024-07-10 11:26:43 +02:00
committed by GitHub
parent 75e7047243
commit 046a34bdfc
232 changed files with 7555 additions and 3818 deletions

View File

@@ -8,7 +8,7 @@ import {
import { TrianglesMini } from "@medusajs/icons"
import { clx } from "@medusajs/ui"
import { useTranslation } from "react-i18next"
import { countries } from "../../../lib/countries"
import { countries } from "../../../lib/data/countries"
export const CountrySelect = forwardRef<
HTMLSelectElement,

View File

@@ -1,7 +1,11 @@
import { Input, Text } from "@medusajs/ui"
import { Input, Text, clx } from "@medusajs/ui"
import { ComponentProps, ElementRef, forwardRef } from "react"
import Primitive from "react-currency-input-field"
export const PercentageInput = forwardRef<
/**
* @deprecated Use `PercentageInput` instead
*/
export const DeprecatedPercentageInput = forwardRef<
ElementRef<typeof Input>,
Omit<ComponentProps<typeof Input>, "type">
>(({ min = 0, max = 100, step = 0.0001, ...props }, ref) => {
@@ -29,4 +33,43 @@ export const PercentageInput = forwardRef<
</div>
)
})
PercentageInput.displayName = "HandleInput"
DeprecatedPercentageInput.displayName = "PercentageInput"
export const PercentageInput = forwardRef<
ElementRef<"input">,
ComponentProps<typeof Primitive>
>(({ min = 0, decimalScale = 2, className, ...props }, ref) => {
return (
<div className="relative">
<Primitive
ref={ref as any} // dependency is typed incorrectly
min={min}
autoComplete="off"
decimalScale={decimalScale}
decimalsLimit={decimalScale}
{...props}
className={clx(
"caret-ui-fg-base 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 pr-10 text-right 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",
className
)}
/>
<div className="absolute inset-y-0 right-0 z-10 flex w-8 items-center justify-center border-l">
<Text
className="text-ui-fg-muted"
size="small"
leading="compact"
weight="plus"
>
%
</Text>
</div>
</div>
)
})
PercentageInput.displayName = "PercentageInput"

View File

@@ -0,0 +1 @@
export * from "./province-select"

View File

@@ -0,0 +1,111 @@
import {
ComponentPropsWithoutRef,
forwardRef,
useImperativeHandle,
useRef,
} from "react"
import { TrianglesMini } from "@medusajs/icons"
import { clx } 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
>(
(
{
className,
disabled,
placeholder,
country_code,
valueAs = "iso_2",
...props
},
ref
) => {
const { t } = useTranslation()
const innerRef = useRef<HTMLSelectElement>(null)
useImperativeHandle(ref, () => innerRef.current as HTMLSelectElement)
const isPlaceholder = innerRef.current?.value === ""
const provinceObject = getCountryProvinceObjectByIso2(country_code)
if (!provinceObject) {
disabled = true
}
const options = Object.entries(provinceObject?.options ?? {}).map(
([iso2, name]) => {
return (
<option key={iso2} value={valueAs === "iso_2" ? iso2 : name}>
{name}
</option>
)
}
)
const placeholderText = provinceObject
? 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 right-2 top-1/2 -translate-y-1/2",
{
"text-ui-fg-disabled": disabled,
}
)}
/>
<select
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>
</div>
)
}
)
ProvinceSelect.displayName = "CountrySelect"